NCEPLIBS-bufr  12.2.0
All Data Structures Namespaces Files Functions Variables Macros Pages
openclosebf.F90
Go to the documentation of this file.
1 
5 
15 recursive subroutine fortran_open(filename, lunit, format, position, iret)
16 
17  use modv_vars, only: im8b
18 
19  implicit none
20  character*(*), intent(in) :: filename, format, position
21  integer, intent(in) :: lunit
22  integer, intent(out) :: iret
23  integer my_lunit
24 
25  ! check for i8 integers
26 
27  if(im8b) then
28  im8b=.false.
29 
30  call x84(lunit,my_lunit,1)
31  call fortran_open(filename,my_lunit,format,position,iret)
32  call x48(iret,iret,1)
33 
34  im8b=.true.
35  return
36  endif
37 
38  open(lunit, file=trim(filename), form=trim(format), position=trim(position), iostat=iret)
39  return
40 end subroutine fortran_open
41 
48 recursive subroutine fortran_close(lunit, iret)
49 
50  use modv_vars, only: im8b
51 
52  implicit none
53  integer, intent(in) :: lunit
54  integer, intent(out) :: iret
55  integer my_lunit
56 
57  ! check for i8 integers
58 
59  if(im8b) then
60  im8b=.false.
61 
62  call x84(lunit,my_lunit,1)
63  call fortran_close(my_lunit,iret)
64  call x48(iret,iret,1)
65 
66  im8b=.true.
67  return
68  endif
69 
70  close(lunit, iostat=iret)
71  return
72 end subroutine fortran_close
73 
167 recursive subroutine openbf(lunit,io,lundx)
168 
169  use bufrlib
170 
171  use modv_vars, only: im8b, ifopbf, nfiles, iprt
172 
173  use moda_msgcwd
174  use moda_stbfr
175  use moda_sc3bfr
176  use moda_lushr
177  use moda_nulbfr
178  use moda_stcode
179 
180  implicit none
181 
182  integer, intent(in) :: lunit, lundx
183  integer my_lunit, my_lundx, iprtprv, lun, il, im
184 
185  character*(*), intent(in) :: io
186  character*255 filename, fileacc
187  character*128 bort_str, errstr
188  character*28 cprint(0:4)
189 
190  data cprint/ &
191  ' (only aborts) ', &
192  ' (limited -default) ', &
193  ' (all warnings) ', &
194  ' (all warnings+infos) ', &
195  ' (all warnings+infos+debugs)'/
196 
197  ! Check for i8 integers
198 
199  if(im8b) then
200  im8b=.false.
201 
202  call x84(lunit,my_lunit,1)
203  call x84(lundx,my_lundx,1)
204  call openbf(my_lunit,io,my_lundx)
205 
206  im8b=.true.
207  return
208  endif
209 
210  if(io=='QUIET') then
211  ! Override previous iprt value
212  iprtprv = iprt
213  iprt = lundx
214  if(iprt<-1) iprt = -1
215  if(iprt>3) iprt = 3
216  if(iprt>=0) then
217  call errwrt('++++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++++')
218  write ( unit=errstr, fmt='(A,I3,A,A,I3,A)' ) 'BUFRLIB: OPENBF - DEGREE OF MESSAGE PRINT INDICATOR CHNGED FROM', &
219  iprtprv,cprint(iprtprv+1),' TO',iprt,cprint(iprt+1)
220  call errwrt(errstr)
221  call errwrt('++++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++++')
222  call errwrt(' ')
223  endif
224  endif
225 
226  if(ifopbf==0) then
227  ! This is the first call to this subroutine, so take care of some initial housekeeping tasks.
228  ! Note that arallocf and arallocc_c must be called before calling bfrini.
229 
230  ! Allocate internal arrays.
231  call arallocf
232  call arallocc_c
233 
234  ! Initialize some global variables.
235  call bfrini
236 
237  ifopbf = 1
238  endif
239  if( (io=='FIRST') .or. (io=='QUIET') ) return
240 
241  ! See if a file can be opened
242 
243  call status(lunit,lun,il,im)
244  if(lun==0) then
245  write(bort_str,'("BUFRLIB: OPENBF - THERE ARE ALREADY",I3," BUFR FILES OPENED, CANNOT OPEN FILE CONNECTED TO UNIT",I4)') &
246  nfiles,lunit
247  call bort(bort_str)
248  endif
249  if(il/=0) then
250  write(bort_str,'("BUFRLIB: OPENBF - THE FILE CONNECTED TO UNIT",I5," IS ALREADY OPEN")') lunit
251  call bort(bort_str)
252  endif
253  null(lun) = 0
254  isc3(lun) = 0
255  iscodes(lun) = 0
256  lus(lun) = 0
257 
258  ! Use inquire to obtain the filename associated with unit lunit
259 
260  if (io/='NUL' .and. io/='INUL') then
261  inquire(lunit,access=fileacc)
262  if(fileacc=='UNDEFINED') open(lunit)
263  inquire(lunit,name=filename)
264  filename=trim(filename)//char(0)
265  endif
266 
267  nmsg(lun) = 0
268  nsub(lun) = 0
269  msub(lun) = 0
270  inode(lun) = 0
271  idate(lun) = 0
272 
273  ! Decide how to open the file and setup the dictionary
274 
275  if(io=='IN') then
276  call openrb_c(lun,filename)
277  call wtstat(lunit,lun,-1,0)
278  call readdx(lunit,lun,lundx)
279  else if(io=='INUL') then
280  call wtstat(lunit,lun,-1,0)
281  if(lunit/=lundx) call readdx(lunit,lun,lundx)
282  null(lun) = 1
283  else if(io=='NUL') then
284  call wtstat(lunit,lun,1,0)
285  if(lunit/=lundx) call readdx(lunit,lun,lundx)
286  null(lun) = 1
287  else if(io=='INX') then
288  call openrb_c(lun,filename)
289  call wtstat(lunit,lun,-1,0)
290  null(lun) = 1
291  else if(io=='OUX') then
292  call openwb_c(lun,filename)
293  call wtstat(lunit,lun,1,0)
294  else if(io=='SEC3') then
295  call openrb_c(lun,filename)
296  call wtstat(lunit,lun,-1,0)
297  isc3(lun) = 1
298  else if(io=='OUT') then
299  call openwb_c(lun,filename)
300  call wtstat(lunit,lun,1,0)
301  call writdx(lunit,lun,lundx)
302  else if(io=='NODX') then
303  call openwb_c(lun,filename)
304  call wtstat(lunit,lun,1,0)
305  call readdx(lunit,lun,lundx)
306  else if(io=='APN' .or. io=='APX') then
307  call openab_c(lun,filename)
308  call wtstat(lunit,lun,1,0)
309  if(lunit/=lundx) call readdx(lunit,lun,lundx)
310  call posapx(lunit)
311  else
312  call bort('BUFRLIB: OPENBF - ILLEGAL SECOND (INPUT) ARGUMENT')
313  endif
314 
315  return
316 end subroutine openbf
317 
330 recursive subroutine closbf(lunit)
331 
332  use bufrlib
333 
334  use modv_vars, only: im8b
335 
336  use moda_nulbfr
337 
338  implicit none
339 
340  character*128 errstr
341 
342  integer, intent(in) :: lunit
343  integer my_lunit, lun, il, im
344 
345  ! Check for i8 integers
346 
347  if(im8b) then
348  im8b=.false.
349 
350  call x84(lunit,my_lunit,1)
351  call closbf(my_lunit)
352 
353  im8b=.true.
354  return
355  endif
356 
357  if ( .not. allocated(null) ) then
358  call errwrt('++++++++++++++++++++WARNING++++++++++++++++++++++')
359  errstr = 'BUFRLIB: CLOSBF WAS CALLED WITHOUT HAVING PREVIOUSLY CALLED OPENBF'
360  call errwrt(errstr)
361  call errwrt('++++++++++++++++++++WARNING++++++++++++++++++++++')
362  return
363  endif
364 
365  call status(lunit,lun,il,im)
366  if(il>0 .and. im/=0) call closmg(lunit)
367  if(il/=0 .and. null(lun)==0) call closfb_c(lun)
368  call wtstat(lunit,lun,0,0)
369 
370  ! Close Fortran unit if null(lun) = 0
371 
372  if(null(lun)==0) close(lunit)
373 
374  return
375 end subroutine closbf
376 
398 recursive subroutine status(lunit,lun,il,im)
399 
400  use modv_vars, only: im8b, nfiles
401 
402  use moda_stbfr
403 
404  implicit none
405 
406  integer, intent(in) :: lunit
407  integer, intent(out) :: lun, il, im
408  integer my_lunit, i
409 
410  character*128 bort_str, errstr
411 
412  ! Check for I8 integers
413 
414  if(im8b) then
415  im8b=.false.
416 
417  call x84(lunit,my_lunit,1)
418  call status(my_lunit,lun,il,im)
419  call x48(lun,lun,1)
420  call x48(il,il,1)
421  call x48(im,im,1)
422 
423  im8b=.true.
424  return
425  endif
426 
427  if(lunit<=0 .or. lunit>99) then
428  write(bort_str,'("BUFRLIB: STATUS - INPUT UNIT NUMBER (",I3,") OUTSIDE LEGAL RANGE OF 1-99")') lunit
429  call bort(bort_str)
430  endif
431 
432  ! Clear the status indicators
433 
434  lun = 0
435  il = 0
436  im = 0
437 
438  ! See if the unit is already connected to the library
439 
440  if ( .not. allocated(iolun) ) then
441  call errwrt('++++++++++++++++++++WARNING++++++++++++++++++++++')
442  errstr = 'BUFRLIB: STATUS WAS CALLED WITHOUT HAVING PREVIOUSLY CALLED OPENBF'
443  call errwrt(errstr)
444  call errwrt('++++++++++++++++++++WARNING++++++++++++++++++++++')
445  return
446  endif
447 
448  do i=1,nfiles
449  if(abs(iolun(i))==lunit) lun = i
450  enddo
451 
452  ! If not, try to define it so as to connect it to the library
453 
454  if(lun==0) then
455  do i=1,nfiles
456  if(iolun(i)==0) then
457  ! File space is available, return with lun > 0, il and im remain 0
458  lun = i
459  return
460  endif
461  enddo
462  ! File space is NOT available, return with lun, il and im all 0
463  return
464  endif
465 
466  ! If the unit was already connected to the library prior to this call, then return statuses
467 
468  il = sign(1,iolun(lun))
469  im = iomsg(lun)
470 
471  return
472 end subroutine status
473 
501 subroutine wtstat(lunit,lun,il,im)
502 
503  use moda_stbfr
504 
505  implicit none
506 
507  integer, intent(in) :: lunit, lun, il, im
508 
509  character*128 bort_str
510 
511  ! Check on the arguments
512 
513  if(lunit<=0) then
514  write(bort_str,'("BUFRLIB: WTSTAT - INVALID UNIT NUMBER PASSED INTO FIRST ARGUMENT (INPUT) (=",I3,")")') lunit
515  call bort(bort_str)
516  endif
517  if(lun<=0) then
518  write(bort_str,'("BUFRLIB: WTSTAT - INVALID FILE ID PASSED INTO SECOND ARGUMENT (INPUT) (=",I3,")")') lun
519  call bort(bort_str)
520  endif
521  if(il<-1 .or. il>1) then
522  write(bort_str,'("BUFRLIB: WTSTAT - INVALID LOGICAL UNIT STATUS INDICATOR PASSED INTO THIRD ARGUMENT '// &
523  '(INPUT) (=",I4,")")') il
524  call bort(bort_str)
525  endif
526  if(im< 0 .or. im>1) then
527  write(bort_str,'("BUFRLIB: WTSTAT - INVALID BUFR MESSAGE STATUS INDICATOR PASSED INTO FOURTH ARGUMENT '// &
528  '(INPUT) (=",I4,")")') im
529  call bort(bort_str)
530  endif
531 
532  ! Check on lunit-lun combination
533 
534  if(abs(iolun(lun))/=lunit .and. (iolun(lun)/=0)) then
535  write(bort_str,'("BUFRLIB: WTSTAT - ATTEMPTING TO REDEFINE EXISTING FILE UNIT (LOGICAL UNIT '// &
536  'NUMBER ",I3,")")') iolun(lun)
537  call bort(bort_str)
538  endif
539 
540  ! Reset the file statuses
541 
542  if(il/=0) then
543  iolun(lun) = sign(lunit,il)
544  iomsg(lun) = im
545  else
546  iolun(lun) = 0
547  iomsg(lun) = 0
548  endif
549 
550  return
551 end subroutine wtstat
552 
578 recursive subroutine ufbcnt(lunit,kmsg,ksub)
579 
580  use modv_vars, only: im8b
581 
582  use moda_msgcwd
583 
584  implicit none
585 
586  integer, intent(in) :: lunit
587  integer, intent(out) :: kmsg, ksub
588  integer my_lunit, lun, il, im
589 
590  ! Check for I8 integers
591 
592  if(im8b) then
593  im8b=.false.
594  call x84(lunit,my_lunit,1)
595  call ufbcnt(my_lunit,kmsg,ksub)
596  call x48(kmsg,kmsg,1)
597  call x48(ksub,ksub,1)
598  im8b=.true.
599  return
600  endif
601 
602  ! Check the file status - return the message and subset counters
603 
604  call status(lunit,lun,il,im)
605  if(il==0) call bort('BUFRLIB: UFBCNT - BUFR FILE IS CLOSED, IT MUST BE OPEN FOR EITHER INPUT OR OUTPUT')
606  kmsg = nmsg(lun)
607  ksub = nsub(lun)
608 
609  return
610 end subroutine ufbcnt
611 
623 subroutine posapx(lunxx)
624 
625  use bufrlib
626 
627  use moda_mgwa
628 
629  implicit none
630 
631  integer, intent(in) :: lunxx
632  integer lunit, lun, il, im, ier, idxmsg
633 
634  lunit = abs(lunxx)
635 
636  call status(lunit,lun,il,im)
637  if(il==0) call bort('BUFRLIB: POSAPX - INPUT BUFR FILE IS CLOSED, IT MUST BE OPEN FOR OUTPUT')
638  if(il<0) call bort('BUFRLIB: POSAPX - INPUT BUFR FILE IS OPEN FOR INPUT, IT MUST BE OPEN FOR OUTPUT')
639 
640  ! Try to read to the end of the file
641 
642  do while (.true.)
643  call rdmsgw(lunit,mgwa,ier)
644  if(ier<0) return
645  if(idxmsg(mgwa)==1) then
646  ! This is an internal dictionary message that was generated by the NCEPLIBS-bufr software. Backspace the file pointer
647  ! and then read and store all such dictionary messages (they should be stored consecutively!) and reset the internal tables.
648  call backbufr_c(lun)
649  call rdbfdx(lunit,lun)
650  endif
651  enddo
652 
653 end subroutine posapx
654 
686 subroutine rewnbf(lunit,isr)
687 
688  use bufrlib
689 
690  use moda_msgcwd
691  use moda_bitbuf
692  use moda_bufrsr
693 
694  implicit none
695 
696  integer, intent(in) :: lunit, isr
697  integer lun, il, im, i, kdate, ier
698 
699  character*128 bort_str
700  character*8 subset
701 
702  ! Try to trap bad call problems
703  if(isr==0) then
704  call status(lunit,lun,il,im)
705  if(jsr(lun)/=0) then
706  write(bort_str,'("BUFRLIB: REWNBF - ATTEMPING TO SAVE '// &
707  'PARAMETERS FOR FILE FOR WHICH THEY HAVE ALREADY BEEN SAVED (AND NOT YET RESTORED) (UNIT",I3,")")') lunit
708  call bort(bort_str)
709  endif
710  if(il==0) then
711  write(bort_str,'("BUFRLIB: REWNBF - ATTEMPING TO SAVE '// &
712  'PARAMETERS FOR BUFR FILE WHICH IS NOT OPENED FOR EITHER INPUT OR OUTPUT) (UNIT",I3,")")') lunit
713  call bort(bort_str)
714  endif
715  elseif(isr==1) then
716  if(junn==0) then
717  write(bort_str,'("BUFRLIB: REWNBF - ATTEMPING TO RESTORE '// &
718  'PARAMETERS TO BUFR FILE WHICH WERE NEVER SAVED (UNIT",I3,")")') lunit
719  call bort(bort_str)
720  endif
721  if(jsr(junn)/=1) then
722  write(bort_str,'("BUFRLIB: REWNBF - ATTEMPING TO RESTORE '// &
723  'PARAMETERS TO BUFR FILE WHICH WERE NEVER SAVED (UNIT",I3,")")') lunit
724  call bort(bort_str)
725  endif
726  lun = junn
727  else
728  write(bort_str,'("BUFRLIB: REWNBF - SAVE/RESTORE SWITCH (INPUT '// &
729  'ARGUMENT ISR) IS NOT ZERO OR ONE (HERE =",I4,") (UNIT",I3,")")') isr, lunit
730  call bort(bort_str)
731  endif
732 
733  if(isr==0) then
734  ! Store the existing file parameters
735  jmsg = nmsg(lun)
736  jsub = nsub(lun)
737  if ( il > 0 ) then
738  ! The file is open for writing
739  jbit = ibit
740  jbyt = mbyt(lun)
741  do i=1,jbyt
742  jbay(i) = mbay(i,lun)
743  enddo
744  endif
745  junn = lun
746  jill = il
747  jimm = im
748  ! Reset the file for reading
749  call wtstat(lunit,lun,-1,0)
750  endif
751 
752  ! Rewind the file
753  call cewind_c(lun)
754 
755  if(isr==1) then
756  ! Restore the previous file parameters. Note that we already restored the previous value of lun earlier in this routine.
757 
758  ! Reset nmsg(lun) to 0, so that the below calls to readmg() will internally restore nmsg(lun) to the correct value.
759  nmsg(lun) = 0
760 
761  ! Note that the below calls to readmg() are valid even if the file was previously open for writing, because we haven't yet
762  ! called wtstat() to restore the file to its previous I/O status. So until then we can still read from it as though it
763  ! was an input file.
764  do i=1,jmsg
765  call readmg(lunit,subset,kdate,ier)
766  if(ier<0) then
767  write(bort_str,'("BUFRLIB: REWNBF - HIT END OF FILE BEFORE '// &
768  'REPOSITIONING BUFR FILE IN UNIT",I3," TO ORIGINAL MESSAGE NO.",I5)') lunit, jmsg
769  call bort(bort_str)
770  endif
771  enddo
772 
773  if ( jill < 0 ) then
774  ! The file was previously open for reading
775  do i=1,jsub
776  call readsb(lunit,ier)
777  enddo
778  else
779  ! The file was previously open for writing
780  do i=1,jbyt
781  mbay(i,lun) = jbay(i)
782  enddo
783  nsub(lun) = jsub
784  mbyt(lun) = jbyt
785  ibit = jbit
786  endif
787 
788  ! Now restore the file to its previous I/O status
789  il = jill
790  im = jimm
791  call wtstat(lunit,lun,il,im)
792  endif
793 
794  ! Toggle the stack status indicator
795  jsr(lun) = mod(jsr(lun)+1,2)
796 
797  return
798 end subroutine rewnbf
799 
854 recursive subroutine ufbtab(lunin,tab,i1,i2,iret,str)
855 
856  use modv_vars, only: im8b, bmiss, iac, iprt
857 
858  use moda_usrint
859  use moda_msgcwd
860  use moda_unptyp
861  use moda_bitbuf
862  use moda_tables
863 
864  implicit none
865 
866  integer*8 ival, lref, ninc, mps, lps
867  integer, intent(in) :: lunin, i1, i2
868  integer, intent(out) :: iret
869  integer, parameter :: maxtg = 100
870  integer nnod, ncon, nods, nodc, ivls, kons, my_lunin, my_i1, my_i2, lunit, lun, il, im, irec, isub, i, n, ntg, &
871  jdate, jbit, kbit, lbit, mbit, nbit, nibit, nbyt, nsb, node, nbmp, nrep, lret, linc, iac_prev, ityp, &
873 
874  character*(*), intent(in) :: str
875  character*128 errstr
876  character*40 cref
877  character*10 tgs(maxtg)
878  character*8 subset, cval
879 
880  logical openit, overflow, just_count, need_node
881 
882  real*8, intent(out) :: tab(i1,i2)
883  real*8 rval, ups
884 
885  common /usrstr/ nnod, ncon, nods(20), nodc(10), ivls(10), kons(10)
886 
887  equivalence(cval,rval)
888 
889  ! Statement functions
890  mps(node) = 2_8**(ibt(node))-1
891  lps(lbit) = max(2_8**(lbit)-1,1)
892 
893  ! Check for I8 integers
894  if(im8b) then
895  im8b=.false.
896  call x84(lunin,my_lunin,1)
897  call x84(i1,my_i1,1)
898  call x84(i2,my_i2,1)
899  call ufbtab(my_lunin,tab,my_i1,my_i2,iret,str)
900  call x48(iret,iret,1)
901  im8b=.true.
902  return
903  endif
904 
905  ! Make sure subroutine openbf() has been called at least once before trying to call subroutine status(); otherwise,
906  ! status() might try to access array space that hasn't yet been dynamically allocated.
907  call openbf(0,'FIRST',0)
908 
909  lunit = abs(lunin)
910  call status(lunit,lun,il,im)
911  openit = il==0
912 
913  if(openit) then
914  ! Open BUFR file connected to unit lunit if it isn't already open
915  call openbf(lunit,'INX',lunit)
916  else
917  ! If BUFR file already opened, save position and rewind to first data message
918  call rewnbf(lunit,0)
919  endif
920 
921  ! Initialize all of the output array values to the current value for "missing"
922  tab(1:i1,1:i2) = bmiss
923 
924  ! Set counters to zero
925  iret = 0
926  irec = 0
927  isub = 0
928 
929  iac_prev = iac
930  iac = 1
931 
932  overflow = .false.
933 
934  ! Check for count subset only option
935  just_count = lunin<lunit
936  if(just_count) then
937  do while(ireadmg(-lunit,subset,jdate)>=0)
938  iret = iret+nmsub(lunit)
939  enddo
940  else
941  ! Check for special tags in string
942  call parstr(str,tgs,maxtg,ntg,' ',.true.)
943  do i=1,ntg
944  if(tgs(i)=='IREC') irec = i
945  if(tgs(i)=='ISUB') isub = i
946  enddo
947  endif
948 
949  outer: do while (.not. just_count)
950  ! Read the next message from the file
951  if(ireadmg(-lunit,subset,jdate)<0) exit
952  call string(str,lun,i1,0)
953  if(irec>0) nods(irec) = 0
954  if(isub>0) nods(isub) = 0
955 
956  if(msgunp(lun)/=2) then
957  ! The message is uncompressed
958 
959  inner1: do while (.true.)
960  ! Get the next subset from the message
961  if(nsub(lun)==msub(lun)) cycle outer
962  if(iret+1>i2) then
963  overflow = .true.
964  exit outer
965  endif
966  iret = iret+1
967  do i=1,nnod
968  nods(i) = abs(nods(i))
969  enddo
970  if(msgunp(lun)==0) then
971  mbit = mbyt(lun)*8 + 16
972  else
973  mbit = mbyt(lun)
974  endif
975  nbit = 0
976  n = 1
977  call usrtpl(lun,n,n)
978  inner2: do while (.true.)
979  ! Cycle through each node of the subset to look for the requested values
980  if(n+1<=nval(lun)) then
981  n = n+1
982  node = inv(n,lun)
983  mbit = mbit+nbit
984  nbit = ibt(node)
985  if(itp(node)==1) then
986  call upb8(ival,nbit,mbit,mbay(1,lun))
987  nbmp=int(ival)
988  call usrtpl(lun,n,nbmp)
989  endif
990  do i=1,nnod
991  if(nods(i)==node) then
992  if(itp(node)==1) then
993  call upb8(ival,nbit,mbit,mbay(1,lun))
994  tab(i,iret) = ival
995  elseif(itp(node)==2) then
996  call upb8(ival,nbit,mbit,mbay(1,lun))
997  if(ival<mps(node)) tab(i,iret) = ups(ival,node)
998  elseif(itp(node)==3) then
999  cval = ' '
1000  kbit = mbit
1001  call upc(cval,nbit/8,mbay(1,lun),kbit,.true.)
1002  tab(i,iret) = rval
1003  endif
1004  nods(i) = -nods(i)
1005  cycle inner2
1006  endif
1007  enddo
1008  do i=1,nnod
1009  if(nods(i)>0) cycle inner2
1010  enddo
1011  endif
1012  exit
1013  enddo inner2
1014  ! Update the subset pointers
1015  if(msgunp(lun)==0) then
1016  ibit = mbyt(lun)*8
1017  call upb(nbyt,16,mbay(1,lun),ibit)
1018  mbyt(lun) = mbyt(lun) + nbyt
1019  else
1020  mbyt(lun) = mbit
1021  endif
1022  nsub(lun) = nsub(lun) + 1
1023  if(irec>0) tab(irec,iret) = nmsg(lun)
1024  if(isub>0) tab(isub,iret) = nsub(lun)
1025  enddo inner1
1026 
1027  else
1028  ! The message is compressed
1029 
1030  if(iret+msub(lun)>i2) then
1031  overflow = .true.
1032  exit outer
1033  endif
1034  if(irec>0.or.isub>0) then
1035  do nsb=1,msub(lun)
1036  if(irec>0) tab(irec,iret+nsb) = nmsg(lun)
1037  if(isub>0) tab(isub,iret+nsb) = nsb
1038  enddo
1039  endif
1040  call usrtpl(lun,1,1)
1041  ibit = mbyt(lun)
1042  n = 0
1043  inner3: do while ( n < nval(lun) )
1044  ! Cycle through each node of each subset to look for the requested values
1045  n = n+1
1046  node = inv(n,lun)
1047  nbit = ibt(node)
1048  ityp = itp(node)
1049  if(n==1) then
1050  ! Reset the node indices
1051  do i=1,nnod
1052  nods(i) = abs(nods(i))
1053  enddo
1054  else
1055  ! Are we still looking for more values?
1056  need_node = .false.
1057  do i=1,nnod
1058  if(nods(i)>0) then
1059  need_node = .true.
1060  exit
1061  endif
1062  enddo
1063  if(.not. need_node) exit inner3
1064  endif
1065  if(ityp==1 .or. ityp==2) then
1066  call up8(lref,nbit,mbay(1,lun),ibit)
1067  call upb(linc,6,mbay(1,lun),ibit)
1068  nibit = ibit + linc*msub(lun)
1069  elseif(ityp==3) then
1070  cref=' '
1071  call upc(cref,nbit/8,mbay(1,lun),ibit,.true.)
1072  call upb(linc,6,mbay(1,lun),ibit)
1073  nibit = ibit + 8*linc*msub(lun)
1074  else
1075  cycle
1076  endif
1077  if(ityp==1) then
1078  ! This is a delayed replication node
1079  jbit = ibit + linc
1080  call up8(ninc,linc,mbay(1,lun),jbit)
1081  ival = lref+ninc
1082  call usrtpl(lun,n,int(ival))
1083  cycle
1084  endif
1085  do i=1,nnod
1086  if(node==nods(i)) then
1087  ! This is one of the requested values, so store the corresponding value from each subset in the message
1088  nods(i) = -nods(i)
1089  lret = iret
1090  if(ityp==1 .or. ityp==2) then
1091  do nsb=1,msub(lun)
1092  jbit = ibit + linc*(nsb-1)
1093  call up8(ninc,linc,mbay(1,lun),jbit)
1094  ival = lref+ninc
1095  lret = lret+1
1096  if(ninc<lps(linc)) tab(i,lret) = ups(ival,node)
1097  enddo
1098  elseif(ityp==3) then
1099  do nsb=1,msub(lun)
1100  if(linc==0) then
1101  cval = cref(1:8)
1102  else
1103  jbit = ibit + linc*(nsb-1)*8
1104  cval = ' '
1105  call upc(cval,linc,mbay(1,lun),jbit,.true.)
1106  endif
1107  lret = lret+1
1108  tab(i,lret) = rval
1109  enddo
1110  else
1111  call bort('UFBTAB - INVALID ELEMENT TYPE SPECIFIED')
1112  endif
1113  endif
1114  enddo
1115  ibit = nibit
1116  enddo inner3
1117  iret = iret+msub(lun)
1118 
1119  endif
1120 
1121  enddo outer
1122 
1123  if(overflow) then
1124  nrep = iret
1125  do while(ireadsb(lunit)==0)
1126  nrep = nrep+1
1127  enddo
1128  do while(ireadmg(-lunit,subset,jdate)>=0)
1129  nrep = nrep+nmsub(lunit)
1130  enddo
1131  if(iprt>=0) then
1132  call errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
1133  write ( unit=errstr, fmt='(A,A,I8,A)' ) 'BUFRLIB: UFBTAB - THE NO. OF DATA SUBSETS IN THE BUFR FILE ', &
1134  .GT.'IS LIMIT OF ', i2, ' IN THE 4TH ARG. (INPUT) - INCOMPLETE READ'
1135  call errwrt(errstr)
1136  write ( unit=errstr, fmt='(A,I8,A,I8,A)' ) '>>>UFBTAB STORED ', iret, ' REPORTS OUT OF ', nrep, '<<<'
1137  call errwrt(errstr)
1138  call errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
1139  call errwrt(' ')
1140  endif
1141  endif
1142 
1143  if(openit) then
1144  ! Close BUFR file if it was opened here
1145  call closbf(lunit)
1146  else
1147  ! Restore BUFR file to its previous status and position
1148  call rewnbf(lunit,1)
1149  endif
1150 
1151  iac = iac_prev
1152 
1153  return
1154 end subroutine ufbtab
subroutine arallocf
Dynamically allocate Fortran language arrays.
Definition: arallocf.F90:19
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
subroutine up8(nval, nbits, ibay, ibit)
Decode an 8-byte integer value from within a specified number of bits of an integer array,...
Definition: cidecode.F90:128
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 writdx(lunit, lun, lundx)
Write DX BUFR table (dictionary) messages to the beginning of an output BUFR file in lunit.
Definition: dxtable.F90:802
subroutine readdx(lunit, lun, lundx)
Initialize modules moda_tababd and moda_msgcwd with DX BUFR (dictionary) tables.
Definition: dxtable.F90:29
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 bfrini
Initialize numerous global variables and arrays within internal modules and common blocks throughout ...
Definition: misc.F90:16
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 arrays and variables needed to store the current position within a BUFR file.
integer jill
File status indicator of BUFR file.
integer jimm
Message status indicator of BUFR file.
integer, dimension(:), allocatable jsr
Indicator of stack status when entering subroutine rewnbf().
integer jmsg
Sequential number of BUFR message, counting from the beginning of the file.
integer jbit
Bit pointer within BUFR message.
integer jsub
Sequential number of BUFR data subset, counting from the beginning of the current BUFR message.
integer junn
File ID of BUFR file.
integer jbyt
Length (in bytes) of BUFR message.
integer, dimension(:), allocatable jbay
BUFR message.
Declare an array used by subroutine makestab() to keep track of which logical units share DX BUFR tab...
integer, dimension(:), allocatable lus
Tracking index 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 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 store a switch for each file ID, indicating whether any BUFR messages should...
integer, dimension(:), allocatable null
Output switch for each file ID:
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 used to store file and message status indicators for all logical units that have been ...
integer, dimension(:), allocatable iolun
File status indicators.
integer, dimension(:), allocatable iomsg
Message status indicator corresponding to iolun, denoting whether a BUFR message is currently open wi...
Declare an array used to store a status code for each file ID if an error or other abnormal result oc...
integer, dimension(:), allocatable iscodes
Abnormal status codes.
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.
subroutine rewnbf(lunit, isr)
Store or restore parameters associated with a BUFR file.
recursive subroutine fortran_open(filename, lunit, format, position, iret)
Open a Fortran file on the local system.
Definition: openclosebf.F90:16
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 fortran_close(lunit, iret)
Close a Fortran file on the local system.
Definition: openclosebf.F90:49
recursive subroutine ufbcnt(lunit, kmsg, ksub)
Get the current location of the file pointer within a BUFR file, in terms of a message number countin...
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 subroutine ufbtab(lunin, tab, i1, i2, iret, str)
Read through every data subset in a BUFR file and return one or more specified data values from each ...
subroutine posapx(lunxx)
Position an output BUFR file for appending.
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 ...
recursive subroutine readmg(lunxx, subset, jdate, iret)
Read the next BUFR message from logical unit abs(lunxx) into internal arrays.
Definition: readwritemg.F90:44
subroutine rdmsgw(lunit, mesg, iret)
Read the next BUFR message from logical unit lunit as an array of integer words.
recursive integer function ireadmg(lunit, subset, idate)
Call subroutine readmg() and pass back its return code as the function value.
subroutine usrtpl(lun, invn, nbmp)
Expand a subset template within internal arrays.
recursive integer function ireadsb(lunit)
Call subroutine readsb() and pass back its return code as the function value.
recursive subroutine readsb(lunit, iret)
Read the next data subset from a BUFR message.
Definition: readwritesb.F90:32
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