NCEPLIBS-bufr  12.3.0
readwritemg.F90
Go to the documentation of this file.
1 
5 
43 recursive subroutine readmg(lunxx,subset,jdate,iret)
44 
45  use bufrlib
46 
47  use modv_vars, only: im8b, iprt
48 
49  use moda_msgcwd
50  use moda_sc3bfr
51  use moda_bitbuf
52 
53  implicit none
54 
55  integer, intent(in) :: lunxx
56  integer, intent(out) :: jdate, iret
57  integer my_lunxx, lunit, lun, il, im, ier, idxmsg, bort_target_set
58 
59  character*8, intent(out) :: subset
60  character*9 csubset
61  character*128 errstr
62 
63  ! Check for I8 integers
64 
65  if(im8b) then
66  im8b = .false.
67  call x84(lunxx,my_lunxx,1)
68  call readmg(my_lunxx,subset,jdate,iret)
69  call x48(jdate,jdate,1)
70  call x48(iret,iret,1)
71  im8b = .true.
72  return
73  endif
74 
75  ! If we're catching bort errors, set a target return location if one doesn't already exist.
76 
77  if (bort_target_set() == 1) then
78  call catch_bort_readmg_c(lunxx,csubset,jdate,len(csubset),iret)
79  subset(1:8) = csubset(1:8)
81  return
82  endif
83 
84  iret = 0
85  lunit = abs(lunxx)
86 
87  ! Check the file status
88 
89  call status(lunit,lun,il,im)
90  if(il==0) call bort('BUFRLIB: READMG - INPUT BUFR FILE IS CLOSED, IT MUST BE OPEN FOR INPUT')
91  if(il>0) call bort('BUFRLIB: READMG - INPUT BUFR FILE IS OPEN FOR OUTPUT, IT MUST BE OPEN FOR INPUT')
92  call wtstat(lunit,lun,il,1)
93 
94  ! Read a message into the internal message buffer
95 
96  do while (.true.)
97  call rdmsgw(lunit,mbay(1,lun),ier)
98  if(ier==-1) then
99  ! EOF on attempted read
100  call wtstat(lunit,lun,il,0)
101  inode(lun) = 0
102  idate(lun) = 0
103  subset = ' '
104  jdate = 0
105  iret = -1
106  return
107  endif
108 
109  ! Parse the message section contents
110  if(isc3(lun)/=0) call reads3(lun)
111  call cktaba(lun,subset,jdate,iret)
112 
113  ! Check for a dictionary message
114  if(idxmsg(mbay(1,lun))/=1) return
115 
116  ! This is an internal dictionary message that was generated by the NCEPLIBS-bufr software.
117  if(isc3(lun)/=0) return
118 
119  ! Section 3 decoding isn't being used, so backspace the file pointer and then use subroutine rdbfdx() to read in
120  ! all such dictionary messages (they should be stored consecutively!) and reset the internal tables.
121  call backbufr_c(lun)
122  call rdbfdx(lunit,lun)
123  if(iprt>=1) then
124  call errwrt('++++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++++')
125  errstr = 'BUFRLIB: READMG - INTERNAL DICTIONARY MESSAGE READ; ACCOUNT FOR IT THEN READ IN NEXT MESSAGE WITHOUT RETURNING'
126  call errwrt(errstr)
127  call errwrt('++++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++++')
128  call errwrt(' ')
129  endif
130  enddo
131 
132 end subroutine readmg
133 
149 recursive integer function ireadmg(lunit,subset,idate) result(iret)
150 
151  use modv_vars, only: im8b
152 
153  implicit none
154 
155  integer, intent(in) :: lunit
156  integer, intent(out) :: idate
157  integer my_lunit
158 
159  character*8, intent(out) :: subset
160 
161  ! Check for I8 integers
162 
163  if(im8b) then
164  im8b = .false.
165  call x84(lunit,my_lunit,1)
166  iret=ireadmg(my_lunit,subset,idate)
167  call x48(idate,idate,1)
168  im8b = .true.
169  return
170  endif
171 
172  call readmg(lunit,subset,idate,iret)
173 
174  return
175 end function ireadmg
176 
220 recursive subroutine readerme(mesg,lunit,subset,jdate,iret)
221 
222  use bufrlib
223 
224  use modv_vars, only: mxmsgl, im8b, nbytw, iprt, bmostr
225 
226  use moda_sc3bfr
227  use moda_idrdm
228  use moda_bitbuf
229 
230  implicit none
231 
232  integer, intent(in) :: lunit, mesg(*)
233  integer, intent(out) :: jdate, iret
234  integer my_lunit, iec0(2), lun, il, im, ii, lnmsg, lmsg, idxmsg, iupbs3, bort_target_set
235 
236  character*8, intent(out) :: subset
237  character*9 csubset
238  character*8 sec0
239  character*128 errstr, bort_str
240 
241  logical endtbl
242 
243  equivalence(sec0,iec0)
244 
245  ! Check for I8 integers
246 
247  if(im8b) then
248  im8b=.false.
249  call x84(lunit,my_lunit,1)
250  call readerme(mesg,my_lunit,subset,jdate,iret)
251  call x48(jdate,jdate,1)
252  call x48(iret,iret,1)
253  im8b=.true.
254  return
255  endif
256 
257  ! If we're catching bort errors, set a target return location if one doesn't already exist.
258 
259  if (bort_target_set() == 1) then
260  call catch_bort_readerme_c(mesg,lunit,csubset,jdate,len(csubset),iret)
261  subset(1:8) = csubset(1:8)
262  call bort_target_unset
263  return
264  endif
265 
266  iret = 0
267 
268  ! Check the file status
269 
270  call status(lunit,lun,il,im)
271  if(il==0) call bort('BUFRLIB: READERME - INPUT BUFR FILE IS CLOSED, IT MUST BE OPEN FOR INPUT')
272  if(il>0) call bort('BUFRLIB: READERME - INPUT BUFR FILE IS OPEN FOR OUTPUT, IT MUST BE OPEN FOR INPUT')
273  call wtstat(lunit,lun,il, 1)
274 
275  ! Copy the input message into the internal message buffer
276 
277  iec0(1) = mesg(1)
278  iec0(2) = mesg(2)
279  lnmsg = lmsg(sec0)
280  if(lnmsg*nbytw>mxmsgl) then
281  write(bort_str,'("BUFRLIB: READERME - INPUT BUFR MESSAGE LENGTH",1X,I6," BYTES) IS LARGER THAN '// &
282  'LIMIT OF ",I6," BYTES")') lnmsg*nbytw, mxmsgl
283  call bort(bort_str)
284  endif
285  do ii=1,lnmsg
286  mbay(ii,lun) = mesg(ii)
287  enddo
288 
289  ! Confirm that the first 4 bytes of SEC0 contain 'BUFR'.
290 
291  if(sec0(1:4)/=bmostr) &
292  call bort('BUFRLIB: READERME - FIRST 4 BYTES READ FROM RECORD NOT "BUFR", DOES NOT CONTAIN BUFR DATA')
293 
294  ! Parse the message section contents
295 
296  if(isc3(lun)/=0) call reads3(lun)
297  call cktaba(lun,subset,jdate,iret)
298  if(isc3(lun)/=0) return
299 
300  ! Check for a DX dictionary message
301 
302  ! A new DX dictionary table can be passed in as a consecutive set of DX dictionary messages. Each message should be passed
303  ! in one at a time, via input argument mesg during consecutive calls to this subroutine, and all such messages will be
304  ! treated as a single dictionary table up until the next message is passed in which either contains no data subsets or
305  ! else is a non-DX dictionary message.
306 
307  endtbl = .false.
308  if(idxmsg(mbay(1,lun))==1) then
309  ! This is a DX dictionary message that was generated by the NCEPLIBS-bufr software.
310  if(iupbs3(mbay(1,lun),'NSUB')==0) then
311  ! But it doesn't contain any actual dictionary information, so assume we've reached the end of the dictionary table.
312  if(idrdm(lun)>0) then
313  endtbl = .true.
314  endif
315  else
316  if(idrdm(lun)==0) then
317  ! This is the first DX dictionary message that is part of a new dictionary table.
318  call dxinit(lun,0)
319  endif
320  idrdm(lun) = idrdm(lun) + 1
321  call stbfdx(lun,mbay(1,lun))
322  endif
323  else if(idrdm(lun)>0) then
324  ! This is the first non-DX dictionary message received following a string of DX dictionary messages, so assume we've
325  ! reached the end of the dictionary table.
326  endtbl = .true.
327  endif
328 
329  if(endtbl) then
330  if ( iprt >= 2 ) then
331  call errwrt('+++++++++++++++++++++++++++++++++++++++++++++++++')
332  write ( unit=errstr, fmt='(A,I3,A)' ) &
333  'BUFRLIB: READERME - STORED NEW DX TABLE CONSISTING OF (', idrdm(lun), ') MESSAGES;'
334  call errwrt(errstr)
335  errstr = 'WILL APPLY THIS TABLE TO ALL SUBSEQUENT DATA MESSAGES UNTIL NEXT DX TABLE IS PASSED IN'
336  call errwrt(errstr)
337  call errwrt('+++++++++++++++++++++++++++++++++++++++++++++++++')
338  call errwrt(' ')
339  endif
340  idrdm(lun) = 0
341  call makestab
342  endif
343 
344  return
345 end subroutine readerme
346 
356 subroutine rdmsgw(lunit,mesg,iret)
357 
358  use bufrlib
359 
360  use modv_vars, only: mxmsgld4
361 
362  implicit none
363 
364  integer, intent(in) :: lunit
365  integer, intent(out) :: mesg(*), iret
366  integer lun, il, im
367 
368  call status(lunit,lun,il,im)
369  iret = -2
370  do while (iret<=-2)
371  iret = crdbufr_c(lun,mesg,mxmsgld4)
372  if(iret==-3) call errwrt('BUFRLIB: RDMSGW - SKIPPING OVERLARGE MESSAGE')
373  if(iret==-2) call errwrt('BUFRLIB: RDMSGW - SKIPPING CORRUPTED MESSAGE')
374  end do
375 
376  return
377 end subroutine rdmsgw
378 
408 recursive subroutine openmb(lunit,subset,jdate)
409 
410  use bufrlib
411 
412  use modv_vars, only: im8b
413 
414  use moda_msgcwd
415 
416  implicit none
417 
418  integer, intent(in) :: lunit, jdate
419  integer my_lunit, my_jdate, lun, il, im, mtyp, mstb, inod, i4dy, lcsb, bort_target_set
420 
421  character*(*), intent(in) :: subset
422  character*9 csubset
423 
424  logical open
425 
426  ! Check for I8 integers
427 
428  if(im8b) then
429  im8b=.false.
430  call x84(lunit,my_lunit,1)
431  call x84(jdate,my_jdate,1)
432  call openmb(my_lunit,subset,my_jdate)
433  im8b=.true.
434  return
435  endif
436 
437  ! If we're catching bort errors, set a target return location if one doesn't already exist.
438 
439  if (bort_target_set() == 1) then
440  call strsuc(subset,csubset,lcsb)
441  call catch_bort_openmb_c(lunit,csubset,lcsb,jdate)
442  call bort_target_unset
443  return
444  endif
445 
446  ! Check the file status
447 
448  call status(lunit,lun,il,im)
449  if(il==0) call bort('BUFRLIB: OPENMB - OUTPUT BUFR FILE IS CLOSED, IT MUST BE OPEN FOR OUTPUT')
450  if(il<0) call bort('BUFRLIB: OPENMB - OUTPUT BUFR FILE IS OPEN FOR INPUT, IT MUST BE OPEN FOR OUTPUT')
451 
452  ! Get some subset particulars
453 
454  call nemtba(lun,subset,mtyp,mstb,inod)
455  open = im==0 .or. inod/=inode(lun) .or. i4dy(jdate)/=idate(lun)
456 
457  ! Maybe(?) open a new or different type of message
458 
459  if(open) then
460  call closmg(lunit)
461  call wtstat(lunit,lun,il, 1)
462  inode(lun) = inod
463  idate(lun) = i4dy(jdate)
464  ! Initialize the open message
465  call msgini(lun)
466  call usrtpl(lun,1,1)
467  endif
468 
469  return
470 end subroutine openmb
471 
490 recursive subroutine openmg(lunit,subset,jdate)
491 
492  use bufrlib
493 
494  use modv_vars, only: im8b
495 
496  use moda_msgcwd
497 
498  implicit none
499 
500  integer, intent(in) :: lunit, jdate
501  integer my_lunit, my_jdate, lun, il, im, mtyp, mstb, inod, i4dy, lcsb, bort_target_set
502 
503  character*(*), intent(in) :: subset
504  character*9 csubset
505 
506  ! Check for I8 integers
507 
508  if(im8b) then
509  im8b=.false.
510  call x84(lunit,my_lunit,1)
511  call x84(jdate,my_jdate,1)
512  call openmg(my_lunit,subset,my_jdate)
513  im8b=.true.
514  return
515  endif
516 
517  ! If we're catching bort errors, set a target return location if one doesn't already exist.
518 
519  if (bort_target_set() == 1) then
520  call strsuc(subset,csubset,lcsb)
521  call catch_bort_openmg_c(lunit,csubset,lcsb,jdate)
522  call bort_target_unset
523  return
524  endif
525 
526  ! Check the file status
527 
528  call status(lunit,lun,il,im)
529  if(il==0) call bort('BUFRLIB: OPENMG - OUTPUT BUFR FILE IS CLOSED, IT MUST BE OPEN FOR OUTPUT')
530  if(il<0) call bort('BUFRLIB: OPENMG - OUTPUT BUFR FILE IS OPEN FOR INPUT, IT MUST BE OPEN FOR OUTPUT')
531  if(im/=0) call closmg(lunit)
532  call wtstat(lunit,lun,il, 1)
533 
534  ! Get some subset particulars
535 
536  call nemtba(lun,subset,mtyp,mstb,inod)
537  inode(lun) = inod
538  idate(lun) = i4dy(jdate)
539 
540  ! Initialize the open message
541 
542  call msgini(lun)
543  call usrtpl(lun,1,1)
544 
545  return
546 end subroutine openmg
547 
564 recursive subroutine closmg(lunin)
565 
566  use bufrlib
567 
568  use modv_vars, only: im8b
569 
570  use moda_msgcwd
571  use moda_msglim
572  use moda_bitbuf
573 
574  implicit none
575 
576  integer, intent(in) :: lunin
577  integer my_lunin, lunit, lun, il, im, bort_target_set
578 
579  ! Check for I8 integers
580 
581  if(im8b) then
582  im8b=.false.
583  call x84(lunin,my_lunin,1)
584  call closmg(my_lunin)
585  im8b=.true.
586  return
587  endif
588 
589  ! If we're catching bort errors, set a target return location if one doesn't already exist.
590 
591  if (bort_target_set() == 1) then
592  call catch_bort_closmg_c(lunin)
593  call bort_target_unset
594  return
595  endif
596 
597  ! Check the file status
598 
599  lunit = abs(lunin)
600  call status(lunit,lun,il,im)
601  if(lunit/=lunin) msglim(lun) = 0
602  if(il==0) call bort('BUFRLIB: CLOSMG - OUTPUT BUFR FILE IS CLOSED, IT MUST BE OPEN FOR OUTPUT')
603  if(il<0) call bort('BUFRLIB: CLOSMG - OUTPUT BUFR FILE IS OPEN FOR INPUT, IT MUST BE OPEN FOR OUTPUT')
604  if(im/=0) then
605  if(nsub(lun)>0) then
606  call msgwrt(lunit,mbay(1,lun),mbyt(lun))
607  else if(nsub(lun)==0.and.nmsg(lun)<msglim(lun)) then
608  call msgwrt(lunit,mbay(1,lun),mbyt(lun))
609  else if(nsub(lun)<0) then
610  call wrcmps(-lunit)
611  endif
612  endif
613  call wtstat(lunit,lun,il,0)
614 
615  return
616 end subroutine closmg
617 
637 subroutine msgwrt(lunit,mesg,mgbyt)
638 
639  use bufrlib
640 
641  use modv_vars, only: mxmsgld4, iprt, nby5, bmostr, bmcstr
642 
643  use moda_nulbfr
644  use moda_bufrmg
645  use moda_mgwa
646  use moda_mgwb
647  use moda_s01cm
648  use moda_tnkrcp
649  use moda_msgstd
650 
651  implicit none
652 
653  integer, intent(in) :: lunit, mgbyt, mesg(*)
654  integer iec0(2), mbyt, ibit, kbit, ii, jj, len0, len1, len2, len3, len4, l5, iad4, iad5, lun, il, im, npbyt, mwrd, &
655  nmwrd, iupbs01, idxmsg
656 
657  character*128 errstr
658 
659  ! Make a local copy of the input message for use within this subroutine, since internal calls to any or all of the
660  ! subroutines stndrd(), cnved4(), pkbs1(), atrcpt(), etc. may end up modifying the message before it finally gets
661  ! written out to lunit.
662 
663  mbyt = mgbyt
664 
665  iec0(1) = mesg(1)
666  iec0(2) = mesg(2)
667  ibit = 32
668  call pkb(mbyt,24,iec0,ibit)
669 
670  do ii = 1, nmwrd(iec0)
671  mgwa(ii) = mesg(ii)
672  enddo
673 
674  ! Overwrite any values within Section 0 or Section 1 that were requested via previous calls to pkvs01(). If a request
675  ! was made to change the BUFR edition number to 4, then actually convert the message as well.
676 
677  if(ns01v>0) then
678  do jj=1,ns01v
679  if(cmnem(jj)=='BEN') then
680  if(ivmnem(jj)==4) then
681  ! Install Section 0 byte count for use by cnved4()
682  ibit = 32
683  call pkb(mbyt,24,mgwa,ibit)
684  call cnved4(mgwa,mxmsgld4,mgwb)
685  ! Compute mbyt for the new edition 4 message
686  mbyt = iupbs01(mgwb,'LENM')
687  ! Copy the mgwb array back into mgwa
688  do ii = 1, nmwrd(mgwb)
689  mgwa(ii) = mgwb(ii)
690  enddo
691  endif
692  else
693  ! Overwrite the requested value
694  call pkbs1(ivmnem(jj),mgwa,cmnem(jj))
695  endif
696  enddo
697  endif
698 
699  ! Standardize the message if requested via module @ref moda_msgstd. However, we don't want to do this if the message
700  ! contains DX BUFR table information, because in that case it's already standard.
701 
702  if ( ( csmf=='Y' ) .and. ( idxmsg(mgwa)/=1 ) ) then
703  ! Install Section 0 byte count and Section 5 '7777' into the original message. This is necessary because
704  ! subroutine stndrd() requires a complete and well-formed BUFR message as its input.
705  ibit = 32
706  call pkb(mbyt,24,mgwa,ibit)
707  ibit = (mbyt-4)*8
708  call pkc(bmcstr,nby5,mgwa,ibit)
709  call stndrd(lunit,mgwa,mxmsgld4,mgwb)
710  ! Compute mbyt for the new standardized message
711  mbyt = iupbs01(mgwb,'LENM')
712  ! Copy the mgwb array back into mgwa
713  do ii = 1, nmwrd(mgwb)
714  mgwa(ii) = mgwb(ii)
715  enddo
716  endif
717 
718  ! Append the tank receipt time to Section 1 if requested via module @ref moda_tnkrcp, unless the message contains
719  ! DX BUFR table information.
720 
721  if ( ( ctrt=='Y' ) .and. ( idxmsg(mgwa)/=1 ) ) then
722  ! Install Section 0 byte count for use by subroutine atrcpt()
723  ibit = 32
724  call pkb(mbyt,24,mgwa,ibit)
725  call atrcpt(mgwa,mxmsgld4,mgwb)
726  ! Compute mbyt for the revised message
727  mbyt = iupbs01(mgwb,'LENM')
728  ! Copy the mgwb array back into mgwa
729  do ii = 1, nmwrd(mgwb)
730  mgwa(ii) = mgwb(ii)
731  enddo
732  endif
733 
734  ! Get the section lengths.
735 
736  call getlens(mgwa,4,len0,len1,len2,len3,len4,l5)
737 
738  ! Depending on the edition number of the message, we need to ensure that each section within the message has an even
739  ! number of bytes.
740 
741  if(iupbs01(mgwa,'BEN')<4) then
742  if(mod(len1,2)/=0) call bort ('BUFRLIB: MSGWRT - LENGTH OF SECTION 1 IS NOT A MULTIPLE OF 2')
743  if(mod(len2,2)/=0) call bort ('BUFRLIB: MSGWRT - LENGTH OF SECTION 2 IS NOT A MULTIPLE OF 2')
744  if(mod(len3,2)/=0) call bort ('BUFRLIB: MSGWRT - LENGTH OF SECTION 3 IS NOT A MULTIPLE OF 2')
745  if(mod(len4,2)/=0) then
746  ! Pad Section 4 with an additional byte that is zeroed out
747  iad4 = len0+len1+len2+len3
748  iad5 = iad4+len4
749  ibit = iad4*8
750  len4 = len4+1
751  call pkb(len4,24,mgwa,ibit)
752  ibit = iad5*8
753  call pkb(0,8,mgwa,ibit)
754  mbyt = mbyt+1
755  endif
756  endif
757 
758  ! Write Section 0 byte count and Section 5
759 
760  ibit = 0
761  call pkc(bmostr, 4,mgwa,ibit)
762  call pkb(mbyt,24,mgwa,ibit)
763 
764  kbit = (mbyt-4)*8
765  call pkc(bmcstr,nby5,mgwa,kbit)
766 
767  ! Zero out the extra bytes which will be written. Note that the BUFR message is stored within the integer array mgwa(*),
768  ! (rather than within a character array), so we need to make sure that the "7777" Is followed by zeroed-out bytes up to
769  ! the boundary of the last machine word that will be written out.
770 
771  call padmsg(mgwa,mxmsgld4,npbyt)
772 
773  ! Write the message plus padding to a word boundary if null(lun) = 0
774 
775  mwrd = nmwrd(mgwa)
776  call status(lunit,lun,il,im)
777  if(null(lun)==0) then
778  call blocks(mgwa,mwrd)
779  call cwrbufr_c(lun,mgwa,mwrd)
780  endif
781 
782  if(iprt>=2) then
783  call errwrt('++++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++++')
784  write ( unit=errstr, fmt='(A,I4,A,I7)') 'BUFRLIB: MSGWRT: LUNIT =', lunit, ', BYTES =', mbyt+npbyt
785  call errwrt(errstr)
786  call errwrt('++++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++++')
787  call errwrt(' ')
788  endif
789 
790  ! Save a memory copy of this message, unless it's a DX message.
791 
792  if(idxmsg(mgwa)/=1) then
793  ! Store a copy of this message within module @ref moda_bufrmg, for possible later retrieval during a future call to
794  ! subroutine writsa()
795  msglen(lun) = mwrd
796  do ii=1,msglen(lun)
797  msgtxt(ii,lun) = mgwa(ii)
798  enddo
799  endif
800 
801  return
802 end subroutine msgwrt
803 
811 subroutine msgini(lun)
812 
813  use modv_vars, only: mtv, nby0, nby1, nby2, nby3, nby5, bmostr, bmcstr, fxy_fbit, fxy_sbyct, fxy_drf8
814 
815  use moda_msgcwd
816  use moda_ufbcpl
817  use moda_bitbuf
818  use moda_tables
819 
820  implicit none
821 
822  integer, intent(in) :: lun
823  integer nby4, nbyt, mtyp, msbt, inod, isub, iret, mcen, mear, mmon, mday, mour, mmin, mbit, ifxy
824 
825  character*128 bort_str
826  character*8 subtag
827  character tab
828 
829  ! Get the message tag and type, and break up the date
830 
831  subtag = tag(inode(lun))(1:8)
832  call nemtba(lun,subtag,mtyp,msbt,inod)
833  if(inode(lun)/=inod) then
834  write(bort_str,'("BUFRLIB: MSGINI - MISMATCH BETWEEN INODE (=",I7,") & POSITIONAL INDEX, INOD (",I7,") '// &
835  'OF SUBTAG (",A,") IN DICTIONARY")') inode(lun), inod, subtag
836  call bort(bort_str)
837  endif
838  call nemtab(lun,subtag,isub,tab,iret)
839  if(iret==0) then
840  write(bort_str,'("BUFRLIB: MSGINI - TABLE A MESSAGE TYPE MNEMONIC ",A," NOT FOUND IN INTERNAL TABLE D ARRAYS")') subtag
841  call bort(bort_str)
842  endif
843 
844  ! Date can be YYMMDDHH or YYYYMMDDHH
845 
846  mcen = mod(idate(lun)/10**8,100)+1
847  mear = mod(idate(lun)/10**6,100)
848  mmon = mod(idate(lun)/10**4,100)
849  mday = mod(idate(lun)/10**2,100)
850  mour = mod(idate(lun) ,100)
851  mmin = 0
852 
853  if(mcen==1) call bort ('BUFRLIB: MSGINI - BUFR MESSAGE DATE (IDATE) is 0000000000')
854 
855  if(mear==0) mcen = mcen-1
856  if(mear==0) mear = 100
857 
858  ! Initialize the message
859 
860  mbit = 0
861  nby4 = 4
862  nbyt = nby0+nby1+nby2+nby3+nby4+nby5
863 
864  ! Section 0
865 
866  call pkc(bmostr, 4 , mbay(1,lun),mbit)
867  call pkb(nbyt , 24 , mbay(1,lun),mbit)
868  call pkb( 3 , 8 , mbay(1,lun),mbit)
869 
870  ! Section 1
871 
872  call pkb(nby1 , 24 , mbay(1,lun),mbit)
873  call pkb( 0 , 8 , mbay(1,lun),mbit)
874  call pkb( 3 , 8 , mbay(1,lun),mbit)
875  call pkb( 7 , 8 , mbay(1,lun),mbit)
876  call pkb( 0 , 8 , mbay(1,lun),mbit)
877  call pkb( 0 , 8 , mbay(1,lun),mbit)
878  call pkb(mtyp , 8 , mbay(1,lun),mbit)
879  call pkb(msbt , 8 , mbay(1,lun),mbit)
880  call pkb( mtv , 8 , mbay(1,lun),mbit)
881  call pkb( 0 , 8 , mbay(1,lun),mbit)
882  call pkb(mear , 8 , mbay(1,lun),mbit)
883  call pkb(mmon , 8 , mbay(1,lun),mbit)
884  call pkb(mday , 8 , mbay(1,lun),mbit)
885  call pkb(mour , 8 , mbay(1,lun),mbit)
886  call pkb(mmin , 8 , mbay(1,lun),mbit)
887  call pkb(mcen , 8 , mbay(1,lun),mbit)
888 
889  ! Section 3
890 
891  call pkb(nby3 , 24 , mbay(1,lun),mbit)
892  call pkb( 0 , 8 , mbay(1,lun),mbit)
893  call pkb( 0 , 16 , mbay(1,lun),mbit)
894  call pkb(2**7 , 8 , mbay(1,lun),mbit)
895  call pkb(ifxy(fxy_sbyct), 16, mbay(1,lun),mbit)
896  call pkb(isub , 16 , mbay(1,lun),mbit)
897  call pkb(ifxy('102000') , 16, mbay(1,lun),mbit)
898  call pkb(ifxy(fxy_drf8) , 16, mbay(1,lun),mbit)
899  call pkb(ifxy('206001') , 16, mbay(1,lun),mbit)
900  call pkb(ifxy(fxy_fbit), 16, mbay(1,lun),mbit)
901  call pkb( 0 , 8 , mbay(1,lun),mbit)
902 
903  ! Section 4
904 
905  call pkb(nby4 , 24 , mbay(1,lun),mbit)
906  call pkb( 0 , 8 , mbay(1,lun),mbit)
907 
908  ! Section 5
909 
910  call pkc(bmcstr,nby5, mbay(1,lun),mbit)
911 
912  ! Double check initial message length
913 
914  if(mod(mbit,8)/=0) call bort('BUFRLIB: MSGINI - INITIALIZED MESSAGE DOES NOT END ON A BYTE BOUNDARY')
915  if(mbit/8/=nbyt) then
916  write(bort_str,'("BUFRLIB: MSGINI - NUMBER OF BYTES STORED FOR INITIALIZED MESSAGE (",I6,") IS NOT THE SAME AS FIRST '// &
917  'CALCULATED, NBYT (",I6)') mbit/8, nbyt
918  call bort(bort_str)
919  endif
920 
921  nmsg(lun) = nmsg(lun)+1
922  nsub(lun) = 0
923  mbyt(lun) = nbyt
924 
925  luncpy(lun)=0
926 
927  return
928 end subroutine msgini
929 
940 logical function msgfull(msiz,itoadd,mxsiz) result(bool)
941 
942  use modv_vars, only: maxnc
943 
944  use moda_tnkrcp
945  use moda_msgstd
946 
947  implicit none
948 
949  integer, intent(in) :: msiz, itoadd, mxsiz
950  integer iwgbyt
951 
952  ! Allow for at least 11 additional bytes of "wiggle room" in the message, because subroutine msgwrt() may do any or all
953  ! of the following:
954  ! 3 bytes may be added by a call to subroutine cnved4()
955  ! + 1 byte (at most) of padding may be added to Section 4
956  ! + 7 bytes (at most) of padding may be added up to the next word boundary after Section 5
957  ! ----
958  ! 11
959  iwgbyt = 11
960 
961  ! But subroutine msgwrt() may also do any of all of the following:
962 
963  ! 6 bytes may be added by a call to subroutine atrcpt()
964  if(ctrt=='Y') iwgbyt = iwgbyt + 6
965 
966  ! (maxnc*2) bytes (at most) may be added by a call to subroutine stndrd()
967  if(csmf=='Y') iwgbyt = iwgbyt + (maxnc*2)
968 
969  ! Determine whether the subset will fit.
970 
971  if ( ( msiz + itoadd + iwgbyt ) > mxsiz ) then
972  bool = .true.
973  else
974  bool = .false.
975  endif
976 
977  return
978 end function msgfull
979 
997 recursive subroutine maxout(maxo)
998 
999  use modv_vars, only: mxmsgl, im8b, iprt
1000 
1001  use moda_bitbuf
1002 
1003  implicit none
1004 
1005  integer, intent(in) :: maxo
1006  integer my_maxo, newsiz, nxstr, ldxa, ldxb, ldxd, ld30
1007 
1008  character*128 errstr
1009  character*56 dxstr
1010 
1011  common /dxtab/ nxstr(10), ldxa(10), ldxb(10), ldxd(10), ld30(10), dxstr(10)
1012 
1013  ! Check for I8 integers
1014 
1015  if(im8b) then
1016  im8b=.false.
1017 
1018  call x84(maxo,my_maxo,1)
1019  call maxout(my_maxo)
1020 
1021  im8b=.true.
1022  return
1023  endif
1024 
1025  if((maxo==0).or.(maxo>mxmsgl)) then
1026  newsiz = mxmsgl
1027  else
1028  newsiz = maxo
1029  endif
1030 
1031  if(iprt>=0) then
1032  if(maxbyt/=newsiz) then
1033  call errwrt('++++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++++')
1034  write ( unit=errstr, fmt='(A,A,I7,A,I7)' ) 'BUFRLIB: MAXOUT - THE RECORD LENGTH OF ALL BUFR MESSAGES ',&
1035  'CREATED FROM THIS POINT ON IS BEING CHANGED FROM ', maxbyt, ' TO ', newsiz
1036  call errwrt(errstr)
1037  call errwrt('++++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++++')
1038  call errwrt(' ')
1039  endif
1040  endif
1041 
1042  maxbyt = newsiz
1043 
1044  return
1045 end subroutine maxout
1046 
1055 integer function igetmxby() result(iret)
1056 
1057  use moda_bitbuf
1058 
1059  implicit none
1060 
1061  iret = maxbyt
1062 
1063  return
1064 end function igetmxby
1065 
1076 subroutine padmsg(mesg,lmesg,npbyt)
1077 
1078  use modv_vars, only: nbytw
1079 
1080  implicit none
1081 
1082  integer, intent(in) :: lmesg
1083  integer, intent(inout) :: mesg(*)
1084  integer, intent(out) :: npbyt
1085  integer nmw, nmb, ibit, i, nmwrd, iupbs01
1086 
1087  ! Make sure that the array is big enough to hold the additional byte padding that will be appended to the
1088  ! end of the message.
1089 
1090  nmw = nmwrd(mesg)
1091  if(nmw>lmesg) call bort('BUFRLIB: PADMSG - CANNOT ADD PADDING TO MESSAGE ARRAY; TRY A LARGER DIMENSION FOR THIS ARRAY')
1092 
1093  ! Pad from the end of the message up to the next 8-byte boundary.
1094 
1095  nmb = iupbs01(mesg,'LENM')
1096  ibit = nmb*8
1097  npbyt = ( nmw * nbytw ) - nmb
1098  do i = 1, npbyt
1099  call pkb(0,8,mesg,ibit)
1100  enddo
1101 
1102  return
1103 end subroutine padmsg
1104 
1115 recursive integer function nmsub(lunit) result(iret)
1116 
1117  use bufrlib
1118 
1119  use modv_vars, only: im8b
1120 
1121  use moda_msgcwd
1122 
1123  implicit none
1124 
1125  integer, intent(in) :: lunit
1126  integer my_lunit, lun, il, im, bort_target_set
1127 
1128  ! Check for I8 integers
1129 
1130  if(im8b) then
1131  im8b=.false.
1132  call x84(lunit,my_lunit,1)
1133  iret=nmsub(my_lunit)
1134  im8b=.true.
1135  return
1136  endif
1137 
1138  ! If we're catching bort errors, set a target return location if one doesn't already exist.
1139 
1140  if (bort_target_set() == 1) then
1141  call catch_bort_nmsub_c(lunit,iret)
1142  call bort_target_unset
1143  return
1144  endif
1145 
1146  iret = 0
1147 
1148  ! Check the file status
1149 
1150  call status(lunit,lun,il,im)
1151  if(il==0) call bort('BUFRLIB: NMSUB - INPUT BUFR FILE IS CLOSED, IT MUST BE OPEN FOR INPUT')
1152  if(il>0) call bort('BUFRLIB: NMSUB - INPUT BUFR FILE IS OPEN FOR OUTPUT, IT MUST BE OPEN FOR INPUT')
1153  if(im==0) call bort('BUFRLIB: NMSUB - A MESSAGE MUST BE OPEN IN INPUT BUFR FILE, NONE ARE')
1154 
1155  iret = msub(lun)
1156 
1157  return
1158 end function nmsub
1159 
1173 integer function nmwrd(mbay) result(iret)
1174 
1175  use modv_vars, only: nbytw
1176 
1177  implicit none
1178 
1179  integer, intent(in) :: mbay(*)
1180  integer lenm, iupbs01
1181 
1182  lenm = iupbs01(mbay,'LENM')
1183  if(lenm==0) then
1184  iret = 0
1185  else
1186  iret = ((lenm/8)+1)*(8/nbytw)
1187  endif
1188 
1189  return
1190 end function nmwrd
1191 
1205 integer function lmsg(sec0) result(iret)
1206 
1207  implicit none
1208 
1209  integer msec0(2), nmwrd
1210 
1211  character*8, intent(in) :: sec0
1212  character*8 csec0
1213 
1214  equivalence(msec0,csec0)
1215 
1216  csec0 = sec0
1217  iret = nmwrd(msec0)
1218 
1219  return
1220 end function lmsg
1221 
1241 recursive subroutine getlens (mbay,ll,len0,len1,len2,len3,len4,len5)
1242 
1243  use modv_vars, only: im8b, nby5
1244 
1245  implicit none
1246 
1247  integer, intent(in) :: mbay(*), ll
1248  integer, intent(out) :: len0, len1, len2, len3, len4, len5
1249  integer my_ll, iad2, iad3, iad4, iupbs01, iupb
1250 
1251  ! Check for I8 integers.
1252  if(im8b) then
1253  im8b=.false.
1254  call x84(ll,my_ll,1)
1255  call getlens(mbay,my_ll,len0,len1,len2,len3,len4,len5)
1256  call x48(len0,len0,1)
1257  call x48(len1,len1,1)
1258  call x48(len2,len2,1)
1259  call x48(len3,len3,1)
1260  call x48(len4,len4,1)
1261  call x48(len5,len5,1)
1262  im8b=.true.
1263  return
1264  endif
1265 
1266  len0 = -1
1267  len1 = -1
1268  len2 = -1
1269  len3 = -1
1270  len4 = -1
1271  len5 = -1
1272 
1273  if(ll<0) return
1274  len0 = iupbs01(mbay,'LEN0')
1275 
1276  if(ll<1) return
1277  len1 = iupbs01(mbay,'LEN1')
1278 
1279  if(ll<2) return
1280  iad2 = len0 + len1
1281  len2 = iupb(mbay,iad2+1,24) * iupbs01(mbay,'ISC2')
1282 
1283  if(ll<3) return
1284  iad3 = iad2 + len2
1285  len3 = iupb(mbay,iad3+1,24)
1286 
1287  if(ll<4) return
1288  iad4 = iad3 + len3
1289  len4 = iupb(mbay,iad4+1,24)
1290 
1291  if(ll<5) return
1292  len5 = nby5
1293 
1294  return
1295 end subroutine getlens
1296 
1321 recursive subroutine cnved4(msgin,lmsgot,msgot)
1322 
1323  use bufrlib
1324 
1325  use modv_vars, only: im8b, nbytw
1326 
1327  implicit none
1328 
1329  integer, intent(in) :: msgin(*), lmsgot
1330  integer, intent(out) :: msgot(*)
1331  integer my_lmsgot, i, nmw, len0, len1, len2, len3, l4, l5, iad2, iad4, lenm, lenmot, len1ot, len3ot, ibit, &
1333 
1334  ! Check for I8 integers.
1335 
1336  if(im8b) then
1337  im8b=.false.
1338  call x84 ( lmsgot, my_lmsgot, 1 )
1339  call cnved4 ( msgin, my_lmsgot*2, msgot )
1340  im8b=.true.
1341  return
1342  endif
1343 
1344  ! If we're catching bort errors, set a target return location if one doesn't already exist.
1345 
1346  if (bort_target_set() == 1) then
1347  call catch_bort_cnved4_c(msgin,lmsgot,msgot)
1348  call bort_target_unset
1349  return
1350  endif
1351 
1352  if(iupbs01(msgin,'BEN')==4) then
1353 
1354  ! The input message is already encoded using edition 4, so just copy it from msgin to msgot and then return.
1355 
1356  nmw = nmwrd(msgin)
1357  if(nmw>lmsgot) &
1358  call bort('BUFRLIB: CNVED4 - OVERFLOW OF OUTPUT (EDITION 4) MESSAGE ARRAY; TRY A LARGER DIMENSION FOR THIS ARRAY')
1359  do i = 1, nmw
1360  msgot(i) = msgin(i)
1361  enddo
1362  return
1363  endif
1364 
1365  ! Get some section lengths and addresses from the input message.
1366 
1367  call getlens(msgin,3,len0,len1,len2,len3,l4,l5)
1368 
1369  iad2 = len0 + len1
1370  iad4 = iad2 + len2 + len3
1371 
1372  lenm = iupbs01(msgin,'LENM')
1373 
1374  ! Check for overflow of the output array. Note that the new edition 4 message will be a total of 3 bytes longer than the
1375  ! input message (i.e. 4 more bytes in Section 1, but 1 fewer byte in Section 3).
1376 
1377  lenmot = lenm + 3
1378  if(lenmot>(lmsgot*nbytw)) &
1379  call bort('BUFRLIB: CNVED4 - OVERFLOW OF OUTPUT (EDITION 4) MESSAGE ARRAY; TRY A LARGER DIMENSION FOR THIS ARRAY')
1380 
1381  len1ot = len1 + 4
1382  len3ot = len3 - 1
1383 
1384  ! Write Section 0 of the new message into the output array.
1385 
1386  call mvb ( msgin, 1, msgot, 1, 4 )
1387  ibit = 32
1388  call pkb ( lenmot, 24, msgot, ibit )
1389  call pkb ( 4, 8, msgot, ibit )
1390 
1391  ! Write Section 1 of the new message into the output array.
1392 
1393  call pkb ( len1ot, 24, msgot, ibit )
1394  call pkb ( iupbs01(msgin,'BMT'), 8, msgot, ibit )
1395  call pkb ( iupbs01(msgin,'OGCE'), 16, msgot, ibit )
1396  call pkb ( iupbs01(msgin,'GSES'), 16, msgot, ibit )
1397  call pkb ( iupbs01(msgin,'USN'), 8, msgot, ibit )
1398  call pkb ( iupbs01(msgin,'ISC2')*128, 8, msgot, ibit )
1399  call pkb ( iupbs01(msgin,'MTYP'), 8, msgot, ibit )
1400  ! Set a default of 255 for the international subcategory.
1401  call pkb ( 255, 8, msgot, ibit )
1402  call pkb ( iupbs01(msgin,'MSBT'), 8, msgot, ibit )
1403  call pkb ( iupbs01(msgin,'MTV'), 8, msgot, ibit )
1404  call pkb ( iupbs01(msgin,'MTVL'), 8, msgot, ibit )
1405  call pkb ( iupbs01(msgin,'YEAR'), 16, msgot, ibit )
1406  call pkb ( iupbs01(msgin,'MNTH'), 8, msgot, ibit )
1407  call pkb ( iupbs01(msgin,'DAYS'), 8, msgot, ibit )
1408  call pkb ( iupbs01(msgin,'HOUR'), 8, msgot, ibit )
1409  call pkb ( iupbs01(msgin,'MINU'), 8, msgot, ibit )
1410  ! Set a default of 0 for the second.
1411  call pkb ( 0, 8, msgot, ibit )
1412 
1413  ! Copy Section 2 (if it exists) through the next-to-last byte of Section 3 from the input array to the output array.
1414 
1415  call mvb ( msgin, iad2+1, msgot, (ibit/8)+1, len2+len3-1 )
1416 
1417  ! Store the length of the new Section 3.
1418 
1419  ibit = ( len0 + len1ot + len2 ) * 8
1420  call pkb ( len3ot, 24, msgot, ibit )
1421 
1422  ! Copy Section 4 and Section 5 from the input array to the output array.
1423 
1424  ibit = ibit + ( len3ot * 8 ) - 24
1425  call mvb ( msgin, iad4+1, msgot, (ibit/8)+1, lenm-iad4 )
1426 
1427  return
1428 end subroutine cnved4
1429 
1441 recursive integer function ifbget(lunit) result(iret)
1442 
1443  use bufrlib
1444 
1445  use modv_vars, only: im8b
1446 
1447  use moda_msgcwd
1448 
1449  implicit none
1450 
1451  integer, intent(in) :: lunit
1452  integer my_lunit, lun, il, im, bort_target_set
1453 
1454  ! Check for I8 integers
1455 
1456  if(im8b) then
1457  im8b=.false.
1458  call x84(lunit,my_lunit,1)
1459  iret=ifbget(my_lunit)
1460  im8b=.true.
1461  return
1462  endif
1463 
1464  ! If we're catching bort errors, set a target return location if one doesn't already exist.
1465 
1466  if (bort_target_set() == 1) then
1467  call catch_bort_ifbget_c(lunit,iret)
1468  call bort_target_unset
1469  return
1470  endif
1471 
1472  iret = -1
1473 
1474  ! Make sure a file/message is open for input
1475 
1476  call status(lunit,lun,il,im)
1477  if(il==0) call bort('BUFRLIB: IFBGET - INPUT BUFR FILE IS CLOSED, IT MUST BE OPEN FOR INPUT')
1478  if(il>0) call bort('BUFRLIB: IFBGET - INPUT BUFR FILE IS OPEN FOR OUTPUT, IT MUST BE OPEN FOR INPUT')
1479  if(im==0) call bort('BUFRLIB: IFBGET - A MESSAGE MUST BE OPEN IN INPUT BUFR FILE, NONE ARE')
1480 
1481  ! Check if there's another subset in the message
1482 
1483  if(nsub(lun)<msub(lun)) iret = 0
1484 
1485  return
1486 end function ifbget
subroutine blocks(mbay, mwrd)
Encapsulate a BUFR message with IEEE Fortran control words as specified via the most recent call to s...
Definition: blocks.F90:37
recursive subroutine bort(str)
Log an error message, then either return to or abort the application program.
Definition: borts.F90:15
subroutine bort_target_unset
Clear any existing bort target.
Definition: borts.F90:180
integer function bort_target_set()
Sets a new bort target, if bort catching is enabled and such a target doesn't already exist.
Definition: borts.F90:160
recursive integer function iupb(mbay, nbyt, nbit)
Decode an integer value from within a specified number of bits of an integer array,...
Definition: cidecode.F90:226
subroutine pkc(chr, nchr, ibay, ibit)
Encode a character string within a specified number of bytes of an integer array, starting at the bit...
Definition: ciencode.F90:25
subroutine pkb(nval, nbits, ibay, ibit)
Encode an integer value within a specified number of bits of an integer array, starting at the bit im...
Definition: ciencode.F90:140
subroutine wrcmps(lunix)
Write a compressed BUFR data subset.
Definition: compress.F90:396
subroutine mvb(ib1, nb1, ib2, nb2, nbm)
Copy a specified number of bytes from one packed binary array to another.
Definition: copydata.F90:767
subroutine nemtba(lun, nemo, mtyp, msbt, inod)
Get information about a Table A descriptor from the internal DX BUFR tables.
Definition: dxtable.F90:1244
subroutine stbfdx(lun, mesg)
Copy a DX BUFR tables message into the internal memory arrays in module moda_tababd.
Definition: dxtable.F90:987
subroutine dxinit(lun, ioi)
Clear out the internal arrays (in module moda_tababd) holding the DX BUFR table, then optionally init...
Definition: dxtable.F90:604
integer function idxmsg(mesg)
Check whether a BUFR message contains DX BUFR tables information that was generated by the NCEPLIBS-b...
Definition: dxtable.F90:1120
subroutine rdbfdx(lunit, lun)
Beginning at the current file pointer location within lunit, read a complete DX BUFR table into inter...
Definition: dxtable.F90:121
subroutine errwrt(str)
Specify a custom location for the logging of error and diagnostic messages generated by the NCEPLIBS-...
Definition: errwrt.F90:32
subroutine nemtab(lun, nemo, idn, tab, iret)
Get information about a descriptor, based on a mnemonic.
Definition: fxy.F90:434
subroutine strsuc(str1, str2, lens)
Remove leading and trailing blanks from a character string.
Definition: misc.F90:199
Wrap C NCEPLIBS-bufr functions so they can be called from within the Fortran part of the library.
Definition: bufrlib.F90:11
Declare arrays and variables used to store BUFR messages internally for multiple file IDs.
integer, dimension(:,:), allocatable mbay
Current BUFR message for each file ID.
integer, dimension(:), allocatable mbyt
Length (in bytes) of current BUFR message for each file ID.
integer maxbyt
Maximum length of an output BUFR message.
Declare arrays used to store, for each output file ID, a copy of the BUFR message that was most recen...
integer, dimension(:), allocatable msglen
Length (in integers) of BUFR message most recently written to each output file ID.
integer, dimension(:,:), allocatable msgtxt
BUFR message most recently written to each output file ID.
Declare an array used by subroutine readerme() to read in a new DX dictionary table as a consecutive ...
integer, dimension(:), allocatable idrdm
DX BUFR tables message count for each file ID.
Declare an array used by various subroutines and functions to hold a temporary working copy of a BUFR...
integer, dimension(:), allocatable mgwa
Temporary working copy of BUFR message.
Declare an array used by various subroutines and functions to hold a temporary working copy of a BUFR...
integer, dimension(:), allocatable mgwb
Temporary working copy of BUFR message.
Declare arrays used to store information about the current BUFR message that is in the process of bei...
integer, dimension(:), allocatable inode
Table A mnemonic for type of BUFR message.
integer, dimension(:), allocatable idate
Section 1 date-time of message.
integer, dimension(:), allocatable nmsg
Current message pointer within logical unit.
integer, dimension(:), allocatable msub
Total number of data subsets in message.
integer, dimension(:), allocatable nsub
Current subset pointer within message.
Declare an array used to keep track of which logical units should not have any empty (zero data subse...
integer, dimension(:), allocatable msglim
Tracking index for each file ID.
Declare a variable used to indicate whether output BUFR messages should be standardized.
character csmf
Flag indicating whether BUFR output messages are to be standardized; this variable is initialized to ...
Declare an array used to store a switch for each file ID, indicating whether any BUFR messages should...
integer, dimension(:), allocatable null
Output switch for each file ID:
Declare arrays and variables used to store custom values for certain mnemonics within Sections 0 and ...
integer, dimension(:), allocatable ivmnem
Custom values for use within Sections 0 and 1 of all future output BUFR messages written to all Fortr...
integer ns01v
Number of custom values stored.
character *8, dimension(:), allocatable cmnem
Section 0 and 1 mnemonics corresponding to ivmnem.
Declare an array used to store a switch for each file ID, indicating whether BUFR messages read from ...
integer, dimension(:), allocatable isc3
Section 3 switch for each file ID:
Declare arrays and variables used to store the internal jump/link table.
character *10, dimension(:), allocatable tag
Mnemonics in the jump/link table.
Declare variables used to store tank receipt time information within Section 1 of BUFR messages.
character ctrt
Flag indicating whether tank receipt times are to be included within output BUFR messages; this varia...
Declare an array used to store, for each file ID, the logical unit number corresponding to a separate...
integer, dimension(:), allocatable luncpy
Logical unit numbers used to copy long character strings between BUFR data subsets.
recursive subroutine status(lunit, lun, il, im)
Check whether a specified Fortran logical unit number is currently connected to the NCEPLIBS-bufr sof...
subroutine wtstat(lunit, lun, il, im)
Update file status in library internals.
subroutine padmsg(mesg, lmesg, npbyt)
Pad a BUFR message with zeroed-out bytes from the end of the message up to the next 8-byte boundary.
recursive subroutine maxout(maxo)
Specify the maximum length of a BUFR message that can be written to any output file by the NCEPLIBS-b...
integer function lmsg(sec0)
Given a character string containing Section 0 from a BUFR message, determine the array size (in integ...
logical function msgfull(msiz, itoadd, mxsiz)
Check whether the current data subset in the internal arrays will fit within the current BUFR message...
recursive subroutine openmg(lunit, subset, jdate)
Open and initialize a new BUFR message within internal arrays, for eventual output to logical unit lu...
recursive subroutine openmb(lunit, subset, jdate)
Open and initialize a new BUFR message within internal arrays, for eventual output to logical unit lu...
recursive subroutine closmg(lunin)
Close the BUFR message that is currently open for writing within internal arrays associated with logi...
recursive integer function nmsub(lunit)
Get the total number of data subsets available within the BUFR message that was most recently opened ...
integer function nmwrd(mbay)
Given an integer array containing Section 0 from a BUFR message, determine the array size (in integer...
integer function igetmxby()
Get the maximum length of a BUFR message that can be written to an output file by the NCEPLIBS-bufr s...
recursive subroutine readerme(mesg, lunit, subset, jdate, iret)
Read a BUFR message from a memory array.
recursive subroutine readmg(lunxx, subset, jdate, iret)
Read the next BUFR message from logical unit abs(lunxx) into internal arrays.
Definition: readwritemg.F90:44
recursive subroutine getlens(mbay, ll, len0, len1, len2, len3, len4, len5)
Read the section lengths of a BUFR message, up to a specified point in the message.
recursive integer function ifbget(lunit)
Check whether there are any more data subsets available to be read from a BUFR message.
subroutine rdmsgw(lunit, mesg, iret)
Read the next BUFR message from logical unit lunit as an array of integer words.
recursive subroutine cnved4(msgin, lmsgot, msgot)
Convert a BUFR edition 3 message to BUFR edition 4.
recursive integer function ireadmg(lunit, subset, idate)
Call subroutine readmg() and pass back its return code as the function value.
subroutine msgini(lun)
Initialize, within the internal arrays, a new uncompressed BUFR message for output.
subroutine msgwrt(lunit, mesg, mgbyt)
Perform final checks and updates on a BUFR message before writing it to a specified Fortran logical u...
subroutine usrtpl(lun, invn, nbmp)
Expand a subset template within internal arrays.
subroutine cktaba(lun, subset, jdate, iret)
Get the Table A mnemonic from Sections 1 and 3 of a BUFR message.
Definition: s013vals.F90:1332
recursive integer function iupbs01(mbay, s01mnem)
Read a specified value from within Section 0 or Section 1 of a BUFR message.
Definition: s013vals.F90:245
recursive subroutine pkbs1(ival, mbay, s1mnem)
Write a specified value into a specified location within Section 1 of a BUFR message,...
Definition: s013vals.F90:524
recursive integer function iupbs3(mbay, s3mnem)
Read a specified value from within Section 3 of a BUFR message.
Definition: s013vals.F90:344
subroutine reads3(lun)
Read the Section 3 descriptors from the BUFR message in mbay(1,lun), then use the BUFR master tables ...
Definition: s013vals.F90:709
recursive integer function i4dy(idate)
Convert a date-time with a 2-digit year (YYMMDDHH) to a date-time with a 4-digit year (YYYYMMDDHH) us...
Definition: s013vals.F90:1118
recursive subroutine stndrd(lunit, msgin, lmsgot, msgot)
Standardize a BUFR message.
Definition: standard.F90:87
recursive subroutine atrcpt(msgin, lmsgot, msgot)
Read an input message and output an equivalent BUFR message with a tank receipt time added to Section...
Definition: tankrcpt.F90:24
subroutine x48(iin4, iout8, nval)
Encode one or more 4-byte integer values as 8-byte integer values.
Definition: x4884.F90:18
subroutine x84(iin8, iout4, nval)
Encode one or more 8-byte integer values as 4-byte integer values.
Definition: x4884.F90:65