NCEPLIBS-bufr  12.2.0
All Data Structures Namespaces Files Functions Variables Macros Pages
memmsgs.F90
Go to the documentation of this file.
1 
5 
38 recursive subroutine ufbmem(lunit,inew,iret,iunit)
39 
40  use bufrlib
41 
42  use modv_vars, only: im8b, maxmem, maxmsg, iprt
43 
44  use moda_mgwa
45  use moda_msgmem
46 
47  implicit none
48 
49  integer, intent(in) :: lunit, inew
50  integer, intent(out) :: iret, iunit
51  integer my_lunit, my_inew, iflg, itim, lun, il, im, itemp, ier, nmsg, lmem, i, mlast0, idxmsg, nmwrd
52 
53  character*128 bort_str, errstr
54 
55  ! Check for I8 integers
56 
57  if(im8b) then
58  im8b=.false.
59 
60  call x84(lunit,my_lunit,1)
61  call x84(inew,my_inew,1)
62  call ufbmem(my_lunit,my_inew,iret,iunit)
63  call x48(iret,iret,1)
64  call x48(iunit,iunit,1)
65 
66  im8b=.true.
67  return
68  endif
69 
70  ! Try to open BUFR file and set to initialize or concatenate
71 
72  call openbf(lunit,'IN',lunit)
73 
74  if(inew==0) then
75  msgp(0) = 0
76  munit = 0
77  mlast = 0
78  ndxts = 0
79  ldxts = 0
80  ndxm = 0
81  ldxm = 0
82  endif
83 
84  nmsg = msgp(0)
85  iret = 0
86  iflg = 0
87  itim = 0
88 
89  ! Copy any BUFR dictionary table messages from the beginning of lunit into @ref moda_msgmem for possible later use.
90  ! Note that such a table (if one exists) is already now in scope due to the prior call to subroutine openbf(), which
91  ! in turn would have automatically called subroutines readdx(), rdbfdx() and makestab() for this table.
92 
93  itemp = ndxts
94  call status(lunit,lun,il,im)
95  call cewind_c(lun)
96  call cpdxmm(lunit)
97 
98  ! If a table was indeed present at the beginning of the file, then set the flag to indicate that this table is now in scope.
99 
100  if ((itemp+1)==ndxts) ldxts = ndxts
101 
102  ! Transfer messages from file to memory and set message pointers
103 
104  do while (.true.)
105  call rdmsgw(lunit,mgwa,ier)
106  if(ier==-1) exit
107  if(ier==-2) then
108  write(bort_str,'("BUFRLIB: UFBMEM - ERROR READING MESSAGE NUMBER",I5," INTO MEMORY FROM UNIT",I3)') nmsg+1,lunit
109  call bort(bort_str)
110  endif
111 
112  if(idxmsg(mgwa)==1) then
113  ! New "embedded" BUFR dictionary table messages have been found in this file. Copy them into @ref moda_msgmem
114  ! for later use.
115  call backbufr_c(lun) ! Backspace lunit
116  call cpdxmm(lunit)
117  cycle
118  endif
119 
120  nmsg = nmsg+1
121  if(nmsg>maxmsg) iflg = 1
122  lmem = nmwrd(mgwa)
123  if(lmem+mlast>maxmem) iflg = 2
124 
125  if(iflg==0) then
126  iret = iret+1
127  do i=1,lmem
128  msgs(mlast+i) = mgwa(i)
129  enddo
130  msgp(0) = nmsg
131  msgp(nmsg) = mlast+1
132  else
133  if(itim==0) then
134  mlast0 = mlast
135  itim=1
136  endif
137  endif
138  mlast = mlast+lmem
139  enddo
140 
141  if(iflg==1) then
142  ! Emergency room treatment for maxmsg array overflow
143  if(iprt>=0) then
144  call errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
145  write ( unit=errstr, fmt='(A,A,I8,A)' ) 'BUFRLIB: UFBMEM - THE NO. OF MESSAGES REQUIRED TO STORE ', &
146  'ALL MESSAGES INTERNALLY EXCEEDS MAXIMUM (', maxmsg, ') - INCOMPLETE READ'
147  call errwrt(errstr)
148  write ( unit=errstr, fmt='(A,I8,A,I8,A)' ) '>>>UFBMEM STORED ', msgp(0), ' MESSAGES OUT OF ', nmsg, '<<<'
149  call errwrt(errstr)
150  write ( unit=errstr, fmt='(A,I8,A,I8,A)' ) '>>>UFBMEM STORED ', mlast0, ' BYTES OUT OF ', mlast, '<<<'
151  call errwrt(errstr)
152  call errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
153  call errwrt(' ')
154  endif
155  mlast=mlast0
156  endif
157 
158  if(iflg==2) then
159  ! Emergency room treatment for maxmem array overflow
160  if(iprt>=0) then
161  call errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
162  write ( unit=errstr, fmt='(A,A,I8,A)' ) 'BUFRLIB: UFBMEM - THE NO. OF BYTES REQUIRED TO STORE ', &
163  'ALL MESSAGES INTERNALLY EXCEEDS MAXIMUM (', maxmem, ') - INCOMPLETE READ'
164  call errwrt(errstr)
165  write ( unit=errstr, fmt='(A,I8,A,I8,A)' ) '>>>UFBMEM STORED ', mlast0, ' BYTES OUT OF ', mlast, '<<<'
166  call errwrt(errstr)
167  write ( unit=errstr, fmt='(A,I8,A,I8,A)' ) '>>>UFBMEM STORED ', msgp(0), ' MESSAGES OUT OF ', nmsg, '<<<'
168  call errwrt(errstr)
169  call errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
170  call errwrt(' ')
171  endif
172  mlast=mlast0
173  endif
174 
175  if(iret==0) then
176  call closbf(lunit)
177  else
178  if(munit/=0) call closbf(lunit)
179  if(munit==0) munit = lunit
180  endif
181  iunit = munit
182 
183  return
184 end subroutine ufbmem
185 
214 recursive subroutine ufbmex(lunit,lundx,inew,iret,mesg)
215 
216  use modv_vars, only: im8b, maxmem, maxmsg, iprt
217 
218  use moda_mgwa
219  use moda_msgmem
220 
221  implicit none
222 
223  character*128 bort_str, errstr
224 
225  integer, intent(in) :: lunit, lundx, inew
226  integer, intent(out) :: mesg(*), iret
227  integer my_lunit, my_lundx, my_inew, nmesg, iflg, itim, ier, nmsg, lmem, i, mlast0, iupbs01, nmwrd
228 
229  ! Check for I8 integers
230 
231  if(im8b) then
232  im8b=.false.
233 
234  call x84(lunit,my_lunit,1)
235  call x84(lundx,my_lundx,1)
236  call x84(inew,my_inew,1)
237  if (my_inew==0) then
238  nmesg = 0
239  else
240  nmesg = msgp(0)
241  call x84(mesg(1),mesg(1),nmesg)
242  endif
243  call ufbmex(my_lunit,my_lundx,my_inew,iret,mesg(1))
244  call x48(mesg(1),mesg(1),nmesg+iret)
245  call x48(iret,iret,1)
246 
247  im8b=.true.
248  return
249  endif
250 
251  ! Try to open BUFR file and set to initialize or concatenate
252 
253  call openbf(lunit,'IN',lundx)
254 
255  if(inew==0) then
256  msgp(0) = 0
257  munit = 0
258  mlast = 0
259  ndxts = 0
260  ldxts = 0
261  ndxm = 0
262  ldxm = 0
263  endif
264 
265  nmsg = msgp(0)
266  iret = 0
267  iflg = 0
268  itim = 0
269 
270  ! Set some flags so that subsequent calls to the message reading routines will know there is a BUFR table in scope.
271 
272  ndxts = 1
273  ldxts = 1
274  ipmsgs(1) = 1
275 
276  ! Transfer messages from file to memory and set message pointers.
277 
278  do while (.true.)
279  call rdmsgw(lunit,mgwa,ier)
280  if(ier==-1) exit
281  if(ier==-2) then
282  write(bort_str,'("BUFRLIB: UFBMEX - ERROR READING MESSAGE NUMBER",I5," INTO MEMORY FROM UNIT",I3)') nmsg+1,lunit
283  call bort(bort_str)
284  endif
285 
286  nmsg = nmsg+1
287  mesg(nmsg) = iupbs01(mgwa,'MTYP')
288  if(nmsg>maxmsg) iflg = 1
289  lmem = nmwrd(mgwa)
290  if(lmem+mlast>maxmem) iflg = 2
291 
292  if(iflg==0) then
293  iret = iret+1
294  do i=1,lmem
295  msgs(mlast+i) = mgwa(i)
296  enddo
297  msgp(0) = nmsg
298  msgp(nmsg) = mlast+1
299  else
300  if(itim==0) then
301  mlast0 = mlast
302  itim=1
303  endif
304  endif
305  mlast = mlast+lmem
306  enddo
307 
308  if(iflg==1) then
309  ! Emergency room treatment for maxmsg array overflow
310  if(iprt>=0) then
311  call errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
312  write ( unit=errstr, fmt='(A,A,I8,A)' ) 'BUFRLIB: UFBMEX - THE NO. OF MESSAGES REQUIRED TO STORE ', &
313  'ALL MESSAGES INTERNALLY EXCEEDS MAXIMUM (', maxmsg, ') - INCOMPLETE READ'
314  call errwrt(errstr)
315  write ( unit=errstr, fmt='(A,I8,A,I8,A)' ) '>>>UFBMEX STORED ', msgp(0), ' MESSAGES OUT OF ', nmsg, '<<<'
316  call errwrt(errstr)
317  write ( unit=errstr, fmt='(A,I8,A,I8,A)' ) '>>>UFBMEX STORED ', mlast0, ' BYTES OUT OF ', mlast, '<<<'
318  call errwrt(errstr)
319  call errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
320  call errwrt(' ')
321  endif
322  mlast=mlast0
323  endif
324 
325  if(iflg==2) then
326  ! Emergency room treatment for maxmem array overflow
327  if(iprt>=0) then
328  call errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
329  write ( unit=errstr, fmt='(A,A,I8,A)' ) 'BUFRLIB: UFBMEX - THE NO. OF BYTES REQUIRED TO STORE ', &
330  'ALL MESSAGES INTERNALLY EXCEEDS MAXIMUM (', maxmem, ') - INCOMPLETE READ'
331  call errwrt(errstr)
332  write ( unit=errstr, fmt='(A,I8,A,I8,A)' ) '>>>UFBMEX STORED ', mlast0, ' BYTES OUT OF ', mlast, '<<<'
333  call errwrt(errstr)
334  write ( unit=errstr, fmt='(A,I8,A,I8,A)' ) '>>>UFBMEX STORED ', msgp(0), ' MESSAGES OUT OF ', nmsg, '<<<'
335  call errwrt(errstr)
336  call errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
337  call errwrt(' ')
338  endif
339  mlast=mlast0
340  endif
341 
342  if(iret==0) then
343  call closbf(lunit)
344  else
345  if(munit/=0) call closbf(lunit)
346  if(munit==0) munit = lunit
347  endif
348 
349  return
350 end subroutine ufbmex
351 
377 recursive subroutine readmm(imsg,subset,jdate,iret)
378 
379  use modv_vars, only: im8b
380 
381  implicit none
382 
383  integer, intent(inout) :: imsg
384  integer, intent(out) :: jdate, iret
385 
386  character*8, intent(out) :: subset
387 
388  ! Check for I8 integers.
389 
390  if(im8b) then
391  im8b=.false.
392 
393  call x84(imsg,imsg,1)
394  call readmm(imsg,subset,jdate,iret)
395  call x48(imsg,imsg,1)
396  call x48(jdate,jdate,1)
397  call x48(iret,iret,1)
398 
399  im8b=.true.
400  return
401  endif
402 
403  call rdmemm(imsg,subset,jdate,iret)
404 
405  imsg = imsg+1
406 
407  return
408 end subroutine readmm
409 
429 recursive integer function ireadmm(imsg,subset,idate) result(iret)
430 
431  use modv_vars, only: im8b
432 
433  implicit none
434 
435  integer, intent(inout) :: imsg
436  integer, intent(out) :: idate
437 
438  character*8, intent(out) :: subset
439 
440  ! Check for I8 integers.
441 
442  if(im8b) then
443  im8b=.false.
444 
445  call x84(imsg,imsg,1)
446  iret=ireadmm(imsg,subset,idate)
447  call x48(imsg,imsg,1)
448  call x48(idate,idate,1)
449 
450  im8b=.true.
451  return
452  endif
453 
454  call readmm(imsg,subset,idate,iret)
455 
456  return
457 end function ireadmm
458 
482 recursive subroutine rdmemm(imsg,subset,jdate,iret)
483 
484  use modv_vars, only: im8b, iprt
485 
486  use moda_msgcwd
487  use moda_bitbuf
488  use moda_mgwa
489  use moda_msgmem
490 
491  implicit none
492 
493  integer, intent(in) :: imsg
494  integer, intent(out) :: jdate, iret
495  integer my_imsg, lun, il, im, ii, jj, kk, nwrd, iptr, lptr, ier
496 
497  character*128 bort_str, errstr
498  character*8, intent(out) :: subset
499 
500  logical known
501 
502  ! Check for I8 integers
503 
504  if(im8b) then
505  im8b=.false.
506 
507  call x84(imsg,my_imsg,1)
508  call rdmemm(my_imsg,subset,jdate,iret)
509  call x48(jdate,jdate,1)
510  call x48(iret,iret,1)
511 
512  im8b=.true.
513  return
514  endif
515 
516  ! Check the message request and file status
517 
518  call status(munit,lun,il,im)
519  call wtstat(munit,lun,il,1)
520  iret = 0
521 
522  if(imsg==0 .or.imsg>msgp(0)) then
523  call wtstat(munit,lun,il,0)
524  if(iprt>=1) then
525  call errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
526  if(imsg==0) then
527  errstr = 'BUFRLIB: RDMEMM - REQUESTED MEMORY MESSAGE NUMBER {FIRST (INPUT) ARGUMENT} IS 0, RETURN WITH IRET = -1'
528  else
529  write ( unit=errstr, fmt='(A,I6,A,I6,A)' ) 'BUFRLIB: RDMEMM - REQ. MEMORY MESSAGE #', imsg, &
530  ' {= 1ST (INPUT) ARG.} > # OF MESSAGES IN MEMORY (', msgp(0), '), RETURN WITH IRET = -1'
531  endif
532  call errwrt(errstr)
533  call errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
534  call errwrt(' ')
535  endif
536  iret = -1
537  return
538  endif
539 
540  ! Determine which table applies to this message.
541 
542  known = .false.
543  jj = ndxts
544  do while ((.not.known).and.(jj>=1))
545  if (ipmsgs(jj)<=imsg) then
546  known = .true.
547  else
548  jj = jj - 1
549  endif
550  enddo
551  if (.not.known) then
552  write(bort_str,'("BUFRLIB: RDMEMM - UNKNOWN DX TABLE FOR REQUESTED MESSAGE #",I5)') imsg
553  call bort(bort_str)
554  endif
555 
556  ! Is this table the one that is currently in scope?
557 
558  if (jj/=ldxts) then
559 
560  ! No, so reset the software to use the proper table.
561 
562  if(iprt>=2) then
563  call errwrt('+++++++++++++++++++++++++++++++++++++++++++++')
564  write ( unit=errstr, fmt='(A,I3,A,I3,A,I6)' ) 'BUFRLIB: RDMEMM - RESETTING TO USE DX TABLE #', jj, &
565  ' INSTEAD OF DX TABLE #', ldxts, ' FOR REQUESTED MESSAGE #', imsg
566  call errwrt(errstr)
567  call errwrt('+++++++++++++++++++++++++++++++++++++++++++++')
568  call errwrt(' ')
569  endif
570  call dxinit(lun,0)
571 
572  ! Store each of the DX dictionary messages which constitute this table.
573 
574  do ii = ifdxts(jj), (ifdxts(jj)+icdxts(jj)-1)
575  if (ii==ndxm) then
576  nwrd = ldxm - ipdxm(ii) + 1
577  else
578  nwrd = ipdxm(ii+1) - ipdxm(ii)
579  endif
580  do kk = 1, nwrd
581  mgwa(kk) = mdx(ipdxm(ii)+kk-1)
582  enddo
583  call stbfdx(lun,mgwa)
584  enddo
585 
586  ! Rebuild the internal jump/link table.
587 
588  call makestab
589  ldxts = jj
590  endif
591 
592  ! Read memory message number imsg into a message buffer.
593 
594  iptr = msgp(imsg)
595  if(imsg<msgp(0)) lptr = msgp(imsg+1)-iptr
596  if(imsg==msgp(0)) lptr = mlast-iptr+1
597  iptr = iptr-1
598 
599  do ii=1,lptr
600  mbay(ii,lun) = msgs(iptr+ii)
601  enddo
602 
603  ! Parse the message section contents.
604 
605  call cktaba(lun,subset,jdate,ier)
606  nmsg(lun) = imsg
607 
608  return
609 end subroutine rdmemm
610 
628 recursive subroutine rdmems(isub,iret)
629 
630  use modv_vars, only: im8b, iprt
631 
632  use moda_msgcwd
633  use moda_unptyp
634  use moda_bitbuf
635  use moda_msgmem
636 
637  implicit none
638 
639  integer, intent(in) :: isub
640  integer, intent(out) :: iret
641  integer my_isub, lun, il, im, mbym, nbyt, i, iupb
642 
643  character*128 bort_str, errstr
644 
645  ! Check for I8 integers
646 
647  if(im8b) then
648  im8b=.false.
649 
650  call x84(isub,my_isub,1)
651  call rdmems(my_isub,iret)
652  call x48(iret,iret,1)
653 
654  im8b=.true.
655  return
656  endif
657 
658  ! Check the message request and file status
659 
660  call status(munit,lun,il,im)
661  if(im==0) call bort('BUFRLIB: RDMEMS - A MEMORY MESSAGE MUST BE OPEN IN INPUT BUFR FILE, NONE ARE')
662  if(nsub(lun)/=0) then
663  write(bort_str,'("BUFRLIB: RDMEMS - UPON ENTRY, SUBSET POINTER IN MEMORY MESSAGE IS NOT AT BEGINNING (",I3," '// &
664  'SUBSETS HAVE BEEN READ, SHOULD BE 0)")') nsub(lun)
665  call bort(bort_str)
666  endif
667 
668  if(isub>msub(lun)) then
669  if(iprt>=0) then
670  call errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
671  write ( unit=errstr, fmt='(A,I5,A,A,I5,A)' ) 'BUFRLIB: RDMEMS - REQ. SUBSET #', isub, ' (= 1st INPUT ', &
672  'ARG.) > # OF SUBSETS IN MEMORY MESSAGE (', msub(lun), ')'
673  call errwrt(errstr)
674  call errwrt('RETURN WITH IRET = -1')
675  call errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
676  call errwrt(' ')
677  endif
678  iret = -1
679  return
680  endif
681 
682  mbym = mbyt(lun)
683  nbyt = 0
684 
685  ! Position to subset number isub in memory message
686 
687  if(msgunp(lun)==0) then
688  nsub(lun) = isub-1
689  do i=1,isub-1
690  mbyt(lun) = mbyt(lun) + iupb(mbay(1,lun),mbyt(lun)+1,16)
691  enddo
692  elseif(msgunp(lun)==1) then
693  ! message with "standard" Section 3
694  do i=1,isub-1
695  call readsb(munit,iret)
696  enddo
697  else
698  ! compressed message
699  nsub(lun) = isub-1
700  endif
701 
702  ! Now read subset number isub from memory message
703 
704  call readsb(munit,iret)
705  if(iret/=0) call bort('BUFRLIB: RDMEMS - CALL TO ROUTINE READSB RETURNED WITH IRET = -1 (EITHER MEMORY MESSAGE '// &
706  'NOT OPEN OR ALL SUBSETS IN MESSAGE READ')
707 
708  ! Reset subset pointer back to zero (beginning of message) and return
709 
710  mbyt(lun) = mbym
711  nsub(lun) = 0
712 
713  return
714 end subroutine rdmems
715 
721 subroutine cpdxmm( lunit )
722 
723  use bufrlib
724 
725  use modv_vars, only: mxdxts, iprt
726 
727  use moda_mgwa
728  use moda_msgmem
729 
730  implicit none
731 
732  integer, intent(in) :: lunit
733  integer ict, lun, il, im, ier, j, lmem, idxmsg, iupbs3, nmwrd
734 
735  character*128 errstr
736 
737  logical done
738 
739  if ( ndxts >= mxdxts ) call bort('BUFRLIB: CPDXMM - MXDXTS OVERFLOW')
740 
741  ict = 0
742  done = .false.
743  call status(lunit,lun,il,im)
744 
745  ! Read a complete dictionary table from lunit, as a set of one or more DX dictionary messages.
746 
747  do while ( .not. done )
748  call rdmsgw ( lunit, mgwa, ier )
749  if ( ier == -2 ) call bort('BUFRLIB: CPDXMM - UNEXPECTED READ ERROR')
750  if ( ier == -1 ) then
751 
752  ! Don't abort for an end-of-file condition, since it may be possible for a file to end with dictionary messages.
753  ! Instead, backspace the file pointer and let the calling routine diagnose the end-of-file condition and deal with
754  ! it as it sees fit.
755 
756  call backbufr_c(lun)
757  done = .true.
758  else if ( idxmsg(mgwa) /= 1 ) then
759 
760  ! This is a non-DX dictionary message. Assume we've reached the end of the dictionary table, and backspace lunit so
761  ! that the next read (e.g. in the calling routine) will get this same message.
762 
763  call backbufr_c(lun)
764  done = .true.
765  else if ( iupbs3(mgwa,'nsub') == 0 ) then
766 
767  ! This is a DX dictionary message, but it doesn't contain any actual dictionary information. Assume we've reached the
768  ! end of the dictionary table.
769 
770  done = .true.
771  else
772 
773  ! Store this message into @ref moda_msgmem.
774 
775  ict = ict + 1
776  if ( ( ndxm + ict ) > mxdxm ) call bort('BUFRLIB: CPDXMM - MXDXM OVERFLOW')
777  ipdxm(ndxm+ict) = ldxm + 1
778  lmem = nmwrd(mgwa)
779  if ( ( ldxm + lmem ) > mxdxw ) call bort('BUFRLIB: CPDXMM - MXDXW OVERFLOW')
780  do j = 1, lmem
781  mdx(ldxm+j) = mgwa(j)
782  enddo
783  ldxm = ldxm + lmem
784  endif
785  enddo
786 
787  ! Update the table information within @ref moda_msgmem.
788 
789  if ( ict > 0 ) then
790  ifdxts(ndxts+1) = ndxm + 1
791  icdxts(ndxts+1) = ict
792  ipmsgs(ndxts+1) = msgp(0) + 1
793  ndxm = ndxm + ict
794  ndxts = ndxts + 1
795  if ( iprt >= 2 ) then
796  call errwrt('+++++++++++++++++++++++++++++++++++++++++++++')
797  write ( unit=errstr, fmt='(A,I3,A,I3,A)') 'BUFRLIB: CPDXMM - STORED NEW DX TABLE #', ndxts, &
798  ' CONSISTING OF ', ict, ' MESSAGES'
799  call errwrt(errstr)
800  call errwrt('+++++++++++++++++++++++++++++++++++++++++++++')
801  call errwrt(' ')
802  endif
803  endif
804 
805  return
806 end subroutine cpdxmm
807 
829 recursive subroutine ufbmms(imsg,isub,subset,jdate)
830 
831  use modv_vars, only: im8b
832 
833  use moda_msgcwd
834  use moda_msgmem
835 
836  implicit none
837 
838  integer, intent(in) :: imsg, isub
839  integer, intent(out) :: jdate
840  integer my_imsg, my_isub, lun, il, im, iret
841 
842  character*8, intent(out) :: subset
843 
844  character*128 bort_str
845 
846  ! Check for I8 integers
847 
848  if(im8b) then
849  im8b=.false.
850 
851  call x84(imsg,my_imsg,1)
852  call x84(isub,my_isub,1)
853  call ufbmms(my_imsg,my_isub,subset,jdate)
854  call x48(jdate,jdate,1)
855 
856  im8b=.true.
857  return
858  endif
859 
860  ! Read subset #isub from memory message #imsg
861 
862  call rdmemm(imsg,subset,jdate,iret)
863  if(iret<0) then
864  if(imsg>0) then
865  write(bort_str,'("BUFRLIB: UFBMMS - REQUESTED MEMORY MESSAGE NUMBER TO READ IN (",I5,") EXCEEDS THE NUMBER OF '// &
866  'MESSAGES IN MEMORY (",I5,")")') imsg,msgp(0)
867  else
868  write(bort_str,'("BUFRLIB: UFBMMS - REQUESTED MEMORY MESSAGE NUMBER TO READ IN IS ZERO - THIS IS NOT VALID")')
869  endif
870  call bort(bort_str)
871  endif
872  call rdmems(isub,iret)
873  if(iret/=0) then
874  call status(munit,lun,il,im)
875  write(bort_str,'("BUFRLIB: UFBMMS - REQ. SUBSET NUMBER TO READ IN (",I3,") EXCEEDS THE NUMBER OF SUBSETS (",I3,") '// &
876  'IN THE REG. MEMORY MESSAGE (",I5,")")') isub,msub(lun),imsg
877  call bort(bort_str)
878  endif
879 
880  return
881 end subroutine ufbmms
882 
900 recursive subroutine ufbmns(irep,subset,idate)
901 
902  use modv_vars, only: im8b
903 
904  use moda_msgmem
905 
906  implicit none
907 
908  integer, intent(in) :: irep
909  integer, intent(out) :: idate
910  integer my_irep, imsg, jrep, iret, ireadmm, nmsub
911 
912  character*8, intent(out) :: subset
913 
914  character*128 bort_str
915 
916  ! Check for I8 integers
917 
918  if(im8b) then
919  im8b=.false.
920 
921  call x84(irep,my_irep,1)
922  call ufbmns(my_irep,subset,idate)
923  call x48(idate,idate,1)
924 
925  im8b=.true.
926  return
927  endif
928 
929  jrep = 0
930  imsg = 1
931 
932  ! Read subset #irep
933 
934  do while(ireadmm(imsg,subset,idate)==0)
935  if(jrep+nmsub(munit)>=irep) then
936  call rdmems(irep-jrep,iret)
937  return
938  endif
939  jrep = jrep+nmsub(munit)
940  enddo
941 
942  write(bort_str,'("BUFRLIB: UFBMNS - REQ. SUBSET NO. TO READ IN (",I5,") EXCEEDS TOTAL NO. OF SUBSETS IN THE COLLECTION '// &
943  'OF MEMORY MESSAGES (",I5,")")') irep,jrep
944  call bort(bort_str)
945 end subroutine ufbmns
946 
966 recursive subroutine ufbrms(imsg,isub,usr,i1,i2,iret,str)
967 
968  use modv_vars, only: im8b, iprt
969 
970  use moda_msgcwd
971  use moda_msgmem
972 
973  implicit none
974 
975  integer, intent(in) :: imsg, isub, i1, i2
976  integer, intent(out) :: iret
977  integer my_imsg, my_isub, my_i1, my_i2, jdate, lun, il, im
978 
979  real*8, intent(out) :: usr(i1,i2)
980 
981  character*(*), intent(in) :: str
982  character*128 bort_str, errstr
983  character*8 subset
984 
985  ! Check for I8 integers
986 
987  if(im8b) then
988  im8b=.false.
989 
990  call x84(imsg,my_imsg,1)
991  call x84(isub,my_isub,1)
992  call x84(i1,my_i1,1)
993  call x84(i2,my_i2,1)
994  call ufbrms(my_imsg,my_isub,usr,my_i1,my_i2,iret,str)
995  call x48(iret,iret,1)
996 
997  im8b=.true.
998  return
999  endif
1000 
1001  iret = 0
1002  if(i1<=0) then
1003  if(iprt>=0) then
1004  call errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
1005  errstr = .LE.'BUFRLIB: UFBRMS - 4th ARG. (INPUT) IS 0, SO RETURN WITH 6th ARG. (IRET) = 0; 7th ARG. (STR) ='
1006  call errwrt(errstr)
1007  call errwrt(str)
1008  call errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
1009  call errwrt(' ')
1010  endif
1011  return
1012  elseif(i2<=0) then
1013  if(iprt>=0) then
1014  call errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
1015  errstr = .LE.'BUFRLIB: UFBRMS - 5th ARG. (INPUT) IS 0, SO RETURN WITH 6th ARG. (IRET) = 0; 7th ARG. (STR) ='
1016  call errwrt(errstr)
1017  call errwrt(str)
1018  call errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
1019  call errwrt(' ')
1020  endif
1021  return
1022  endif
1023 
1024  ! Read requested values from subset #isub within memory message #imsg
1025 
1026  call rdmemm(imsg,subset,jdate,iret)
1027  if(iret<0) then
1028  if(imsg>0) then
1029  write(bort_str,'("BUFRLIB: UFBRMS - REQUESTED MEMORY MESSAGE NUMBER TO READ IN (",I5,") EXCEEDS THE NUMBER OF '// &
1030  'MESSAGES IN MEMORY (",I5,")")') imsg,msgp(0)
1031  else
1032  write(bort_str,'("BUFRLIB: UFBRMS - REQUESTED MEMORY MESSAGE NUMBER TO READ IN IS ZERO - THIS IS NOT VALID")')
1033  endif
1034  call bort(bort_str)
1035  endif
1036  call rdmems(isub,iret)
1037  if(iret/=0) then
1038  call status(munit,lun,il,im)
1039  write(bort_str,'("BUFRLIB: UFBRMS - REQ. SUBSET NUMBER TO READ IN (",I3,") EXCEEDS THE NUMBER OF SUBSETS (",I3,") '// &
1040  'IN THE REG. MEMORY MESSAGE (",I5,")")') isub,msub(lun),imsg
1041  call bort(bort_str)
1042  endif
1043 
1044  call ufbint(munit,usr,i1,i2,iret,str)
1045 
1046  return
1047 end subroutine ufbrms
1048 
1090 recursive subroutine ufbtam(tab,i1,i2,iret,str)
1091 
1092  use modv_vars, only: im8b, bmiss, iprt
1093 
1094  use moda_usrint
1095  use moda_msgcwd
1096  use moda_bitbuf
1097  use moda_msgmem
1098  use moda_tables
1099 
1100  implicit none
1101 
1102  character*(*), intent(in) :: str
1103  character*128 bort_str, errstr
1104  character*10 tgs(100)
1105  character*8 subset, cval
1106 
1107  integer*8 mps, ival
1108  integer, intent(in) :: i1, i2
1109  integer, intent(out) :: iret
1110  integer maxtg, nnod, ncon, nods, nodc, ivls, kons, my_i1, my_i2, i, irec, isub, itbl, lun, il, im, jdate, mret, &
1111  kbit, mbit, nbit, n, node, imsg, kmsg, nrep, ntg, nbyt, nbmp, nmsub
1112 
1113  real*8, intent(out) :: tab(i1,i2)
1114  real*8 rval, ups
1115 
1116  common /usrstr/ nnod,ncon,nods(20),nodc(10),ivls(10),kons(10)
1117 
1118  equivalence(cval,rval)
1119 
1120  data maxtg /100/
1121 
1122  ! Statement function
1123  mps(node) = 2_8**(ibt(node))-1
1124 
1125  ! Check for I8 integers
1126 
1127  if(im8b) then
1128  im8b=.false.
1129 
1130  call x84(i1,my_i1,1)
1131  call x84(i2,my_i2,1)
1132  call ufbtam(tab,my_i1,my_i2,iret,str)
1133  call x48(iret,iret,1)
1134 
1135  im8b=.true.
1136  return
1137  endif
1138 
1139  iret = 0
1140 
1141  if(msgp(0)==0) return
1142 
1143  tab(1:i1,1:i2) = bmiss
1144 
1145  ! Check for special tags in string
1146 
1147  call parstr(str,tgs,maxtg,ntg,' ',.true.)
1148  irec = 0
1149  isub = 0
1150  itbl = 0
1151  do i=1,ntg
1152  if(tgs(i)=='IREC') irec = i
1153  if(tgs(i)=='ISUB') isub = i
1154  if(tgs(i)=='ITBL') itbl = i
1155  enddo
1156 
1157  call status(munit,lun,il,im)
1158 
1159  ! Cycle through all of the memory messages in the internal arrays
1160 
1161  outer: do imsg=1,msgp(0)
1162  call rdmemm(imsg,subset,jdate,mret)
1163  if(mret<0) then
1164  write(bort_str,'("BUFRLIB: UFBTAM - HIT END-OF-FILE READING MESSAGE NUMBER",I5," IN INTERNAL MEMORY")') imsg
1165  call bort(bort_str)
1166  endif
1167 
1168  call string(str,lun,i1,0)
1169  if(irec>0) nods(irec) = 0
1170  if(isub>0) nods(isub) = 0
1171  if(itbl>0) nods(itbl) = 0
1172 
1173  ! Process all the subsets in the memory message
1174 
1175  do while (nsub(lun)<msub(lun))
1176  if(iret+1>i2) then
1177  ! Emergency room treatment for array overflow
1178  call rdmemm(0,subset,jdate,mret)
1179  nrep = 0
1180  do kmsg=1,msgp(0)
1181  call rdmemm(kmsg,subset,jdate,mret)
1182  if(mret<0) then
1183  write(bort_str,'("BUFRLIB: UFBTAM - HIT END-OF-FILE READING MESSAGE NUMBER",I5," IN INTERNAL MEMORY")') kmsg
1184  call bort(bort_str)
1185  endif
1186  nrep = nrep+nmsub(munit)
1187  enddo
1188  if(iprt>=0) then
1189  call errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
1190  write ( unit=errstr, fmt='(A,A,I8,A,A)' ) 'BUFRLIB: UFBTAM - THE NO. OF DATA SUBSETS IN MEMORY ', &
1191  .GT.'IS LIMIT OF ', i2, ' IN THE 3RD ARG. (INPUT) - INCOMPLETE READ'
1192  call errwrt(errstr)
1193  write ( unit=errstr, fmt='(A,I8,A,I8,A)' ) '>>>UFBTAM STORED ', iret, ' REPORTS OUT OF ', nrep, '<<<'
1194  call errwrt(errstr)
1195  call errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
1196  call errwrt(' ')
1197  endif
1198  exit outer
1199  endif
1200 
1201  iret = iret+1
1202 
1203  do i=1,nnod
1204  nods(i) = abs(nods(i))
1205  enddo
1206 
1207  call usrtpl(lun,1,1)
1208  mbit = mbyt(lun)*8+16
1209  nbit = 0
1210  n = 1
1211 
1212  inner: do while(n+1<=nval(lun))
1213  n = n+1
1214  node = inv(n,lun)
1215  mbit = mbit+nbit
1216  nbit = ibt(node)
1217  if(itp(node)==1) then
1218  call upb8(ival,nbit,mbit,mbay(1,lun))
1219  nbmp=int(ival)
1220  call usrtpl(lun,n,nbmp)
1221  endif
1222  do i=1,nnod
1223  if(nods(i)==node) then
1224  if(itp(node)==1) then
1225  call upb8(ival,nbit,mbit,mbay(1,lun))
1226  tab(i,iret) = ival
1227  elseif(itp(node)==2) then
1228  call upb8(ival,nbit,mbit,mbay(1,lun))
1229  if(ival<mps(node)) tab(i,iret) = ups(ival,node)
1230  elseif(itp(node)==3) then
1231  cval = ' '
1232  kbit = mbit
1233  call upc(cval,nbit/8,mbay(1,lun),kbit,.true.)
1234  tab(i,iret) = rval
1235  endif
1236  nods(i) = -nods(i)
1237  cycle inner
1238  endif
1239  enddo
1240  do i=1,nnod
1241  if(nods(i)>0) cycle inner
1242  enddo
1243  enddo inner
1244 
1245  ! Update the subset pointers before next read
1246 
1247  ibit = mbyt(lun)*8
1248  call upb(nbyt,16,mbay(1,lun),ibit)
1249  mbyt(lun) = mbyt(lun) + nbyt
1250  nsub(lun) = nsub(lun) + 1
1251  if(irec>0) tab(irec,iret) = nmsg(lun)
1252  if(isub>0) tab(isub,iret) = nsub(lun)
1253  if(itbl>0) tab(itbl,iret) = ldxts
1254  enddo
1255 
1256  enddo outer
1257 
1258  ! Reset the memory file
1259  call rdmemm(0,subset,jdate,mret)
1260 
1261  return
1262 end subroutine ufbtam
subroutine bort(str)
Log an error message, then abort the application program.
Definition: borts.F90:15
subroutine upb(nval, nbits, ibay, ibit)
Decode an integer value from within a specified number of bits of an integer array,...
Definition: cidecode.F90:202
subroutine upb8(nval, nbits, ibit, ibay)
Decode an 8-byte integer value from within a specified number of bits of an integer array,...
Definition: cidecode.F90:80
real *8 function ups(ival, node)
Unpack a real*8 value from an integer by applying the proper scale and reference values.
Definition: cidecode.F90:319
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 upc(chr, nchr, ibay, ibit, cnvnull)
Decode a character string from within a specified number of bytes of an integer array,...
Definition: cidecode.F90:26
subroutine stbfdx(lun, mesg)
Copy a DX BUFR tables message into the internal memory arrays in module moda_tababd.
Definition: dxtable.F90:981
subroutine dxinit(lun, ioi)
Clear out the internal arrays (in module moda_tababd) holding the DX BUFR table, then optionally init...
Definition: dxtable.F90:606
integer function idxmsg(mesg)
Check whether a BUFR message contains DX BUFR tables information that was generated by the NCEPLIBS-b...
Definition: dxtable.F90:1114
subroutine errwrt(str)
Specify a custom location for the logging of error and diagnostic messages generated by the NCEPLIBS-...
Definition: errwrt.F90:32
recursive subroutine rdmems(isub, iret)
Read a specified data subset from the BUFR message that was most recently read via a call to subrouti...
Definition: memmsgs.F90:629
subroutine cpdxmm(lunit)
Read an entire DX BUFR table from a specified file into internal memory arrays.
Definition: memmsgs.F90:722
recursive subroutine rdmemm(imsg, subset, jdate, iret)
Read a specified BUFR message from internal arrays in memory, so that it is now in scope for processi...
Definition: memmsgs.F90:483
recursive subroutine ufbmem(lunit, inew, iret, iunit)
Connect a new file to the NCEPLIBS-bufr software for input operations, then read the entire file cont...
Definition: memmsgs.F90:39
recursive subroutine readmm(imsg, subset, jdate, iret)
Read a specified BUFR message from internal arrays in memory, so that it is now in scope for processi...
Definition: memmsgs.F90:378
recursive subroutine ufbmex(lunit, lundx, inew, iret, mesg)
Connect a new file to the NCEPLIBS-bufr software for input operations, then read the entire file cont...
Definition: memmsgs.F90:215
recursive subroutine ufbmns(irep, subset, idate)
Read a specified data subset from internal arrays in memory, so that it is now in scope for processin...
Definition: memmsgs.F90:901
recursive subroutine ufbrms(imsg, isub, usr, i1, i2, iret, str)
Read one or more data values from a data subset in internal arrays.
Definition: memmsgs.F90:967
recursive subroutine ufbtam(tab, i1, i2, iret, str)
Read through every data subset in internal arrays and return one or more specified data values from e...
Definition: memmsgs.F90:1091
recursive subroutine ufbmms(imsg, isub, subset, jdate)
Read a specified data subset from internal arrays.
Definition: memmsgs.F90:830
recursive integer function ireadmm(imsg, subset, idate)
Call subroutine readmm() and pass back its return code as the function value.
Definition: memmsgs.F90:430
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 ibit
Bit pointer within ibay.
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.
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 arrays used to store information about the current BUFR message that is in the process of bei...
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 arrays and variables used to store the contents of one or more BUFR files within internal mem...
integer, dimension(:), allocatable msgp
Pointers to the beginning of each message within msgs (up to a maximum of maxmsg, and where array ele...
integer, dimension(:), allocatable ipmsgs
Pointers to first message within msgs for which each DX BUFR table applies.
integer, dimension(:), allocatable msgs
BUFR messages read from one or more BUFR files.
integer, dimension(:), allocatable icdxts
Number of consecutive messages within mdx which constitute each DX BUFR table, beginning with the cor...
integer mxdxm
Maximum number of DX BUFR table messages that can be stored within mdx.
integer, dimension(:), allocatable ifdxts
Pointers to the beginning of each DX BUFR table within mdx.
integer munit
Fortran logical unit number for use in accessing contents of BUFR files within internal memory.
integer ndxm
Number of DX BUFR table messages stored within mdx (up to a maximum of mxdxm).
integer ldxm
Number of array elements filled within mdx (up to a maximum of mxdxw).
integer mlast
Number of array elements filled within msgs (up to a maximum of maxmem).
integer ldxts
Number of DX BUFR table that is currently in scope, depending on which BUFR message within msgs is cu...
integer ndxts
Number of DX BUFR tables represented by the messages within mdx (up to a maximum of mxdxts).
integer, dimension(:), allocatable mdx
DX BUFR table messages read from one or more BUFR files, for use in decoding the messages in msgs.
integer mxdxw
Maximum number of entries that can be stored within mdx.
integer, dimension(:), allocatable ipdxm
Pointers to the beginning of each message within mdx.
Declare arrays and variables used to store the internal jump/link table.
integer, dimension(:), allocatable ibt
Bit widths corresponding to tag and typ:
integer, dimension(:), allocatable itp
Integer type values corresponding to typ:
Declare an array used to store, for each file ID from which a BUFR message is currently being read as...
integer, dimension(:), allocatable msgunp
Flag indicating how to unpack data subsets from BUFR message:
Declare arrays used to store data values and associated metadata for the current BUFR data subset in ...
integer, dimension(:), allocatable nval
Number of data values in BUFR data subset.
integer, dimension(:,:), allocatable, target inv
Inventory pointer which links each data value to its corresponding node in the internal jump/link tab...
recursive subroutine closbf(lunit)
Close the connection between logical unit lunit and the NCEPLIBS-bufr software.
recursive subroutine openbf(lunit, io, lundx)
Connect a new file to the NCEPLIBS-bufr software for input or output operations, or initialize the li...
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.
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...
subroutine rdmsgw(lunit, mesg, iret)
Read the next BUFR message from logical unit lunit as an array of integer words.
subroutine usrtpl(lun, invn, nbmp)
Expand a subset template within internal arrays.
recursive subroutine readsb(lunit, iret)
Read the next data subset from a BUFR message.
Definition: readwritesb.F90:32
recursive subroutine ufbint(lunin, usr, i1, i2, iret, str)
Read or write one or more data values from or to a data subset.
subroutine cktaba(lun, subset, jdate, iret)
Get the Table A mnemonic from Sections 1 and 3 of a BUFR message.
Definition: s013vals.F90:1265
recursive integer function iupbs01(mbay, s01mnem)
Read a specified value from within Section 0 or Section 1 of a BUFR message.
Definition: s013vals.F90:247
subroutine parstr(str, tags, mtag, ntag, sep, limit80)
Parse a string containing one or more substrings into an array of substrings.
Definition: strings.F90:473
subroutine string(str, lun, i1, io)
Check whether a string is in the internal mnemonic string cache.
Definition: strings.F90:25
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