NCEPLIBS-bufr  12.3.0
copydata.F90
Go to the documentation of this file.
1 
5 
22 recursive subroutine copybf(lunin,lunot)
23 
24  use bufrlib
25 
26  use modv_vars, only: im8b
27 
28  use moda_mgwa
29 
30  implicit none
31 
32  integer, intent(in) :: lunin, lunot
33  integer my_lunin, my_lunot, lun, il, im, ier, iupbs01, bort_target_set
34 
35  ! Check for I8 integers
36 
37  if(im8b) then
38  im8b=.false.
39  call x84(lunin,my_lunin,1)
40  call x84(lunot,my_lunot,1)
41  call copybf(my_lunin,my_lunot)
42  im8b=.true.
43  return
44  endif
45 
46  ! If we're catching bort errors, set a target return location if one doesn't already exist.
47 
48  if (bort_target_set() == 1) then
49  call catch_bort_copybf_c(lunin,lunot)
51  return
52  endif
53 
54  ! Check BUFR file statuses
55 
56  call status(lunin,lun,il,im)
57  if(il/=0) call bort ('BUFRLIB: COPYBF - INPUT BUFR FILE IS OPEN, IT MUST BE CLOSED')
58  call status(lunot,lun,il,im)
59  if(il/=0) call bort ('BUFRLIB: COPYBF - OUTPUT BUFR FILE IS OPEN, IT MUST BE CLOSED')
60 
61  ! Connect the files for reading/writing to the C I/O interface
62 
63  call openbf(lunin,'INX',lunin)
64  call openbf(lunot,'OUX',lunin)
65 
66  ! Read and copy a BUFR file from unit lunin to unit lunot
67 
68  ier = 0
69  do while (ier==0)
70  call rdmsgw(lunin,mgwa,ier)
71  if(ier==0) call msgwrt(lunot,mgwa,iupbs01(mgwa,'LENM'))
72  enddo
73 
74  ! Free up the file connections for the two files
75 
76  call closbf(lunin)
77  call closbf(lunot)
78 
79  return
80 end subroutine copybf
81 
115 recursive subroutine copymg(lunin,lunot)
116 
117  use bufrlib
118 
119  use modv_vars, only: im8b
120 
121  use moda_msgcwd
122  use moda_bitbuf
123  use moda_tables
124 
125  implicit none
126 
127  integer, intent(in) :: lunin, lunot
128  integer my_lunin, my_lunot, lin, lot, il, im, mtyp, msbt, inod, mbym, iupbs01, iok2cpy, bort_target_set
129 
130  character*8 subset
131 
132  ! Check for I8 integers
133 
134  if(im8b) then
135  im8b=.false.
136  call x84(lunin,my_lunin,1)
137  call x84(lunot,my_lunot,1)
138  call copymg(my_lunin,my_lunot)
139  im8b=.true.
140  return
141  endif
142 
143  ! If we're catching bort errors, set a target return location if one doesn't already exist.
144 
145  if (bort_target_set() == 1) then
146  call catch_bort_copymg_c(lunin,lunot)
147  call bort_target_unset
148  return
149  endif
150 
151  ! Check the file statuses
152 
153  call status(lunin,lin,il,im)
154  if(il==0) call bort('BUFRLIB: COPYMG - INPUT BUFR FILE IS CLOSED, IT MUST BE OPEN FOR INPUT')
155  if(il>0) call bort('BUFRLIB: COPYMG - INPUT BUFR FILE IS OPEN FOR OUTPUT, IT MUST BE OPEN FOR INPUT')
156  if(im==0) call bort('BUFRLIB: COPYMG - A MESSAGE MUST BE OPEN IN INPUT BUFR FILE, NONE ARE')
157 
158  call status(lunot,lot,il,im)
159  if(il==0) call bort('BUFRLIB: COPYMG - OUTPUT BUFR FILE IS CLOSED, IT MUST BE OPEN FOR OUTPUT')
160  if(il<0) call bort('BUFRLIB: COPYMG - OUTPUT BUFR FILE IS OPEN FOR INPUT, IT MUST BE OPEN FOR OUTPUT')
161  if(im/=0) call bort('BUFRLIB: COPYMG - ALL MESSAGES MUST BE CLOSED IN OUTPUT BUFR FILE, A MESSAGE IS OPEN')
162 
163  ! Make sure both files have the same tables
164 
165  subset = tag(inode(lin))(1:8)
166  call nemtba(lot,subset,mtyp,msbt,inod)
167  if(inode(lin)/=inod .and. iok2cpy(lin,lot)/=1) &
168  call bort('BUFRLIB: COPYMG - INPUT AND OUTPUT BUFR FILES MUST HAVE THE SAME INTERNAL TABLES, THEY ARE DIFFERENT HERE')
169 
170  ! Everything okay, so copy a message
171 
172  mbym = iupbs01(mbay(1,lin),'LENM')
173  call msgwrt(lunot,mbay(1,lin),mbym)
174 
175  ! Set the message control words for partition associated with lunot
176 
177  nmsg(lot) = nmsg(lot) + 1
178  nsub(lot) = msub(lin)
179  msub(lot) = msub(lin)
180  idate(lot) = idate(lin)
181  inode(lot) = inod
182 
183  return
184 end subroutine copymg
185 
218 recursive subroutine copysb(lunin,lunot,iret)
219 
220  use bufrlib
221 
222  use modv_vars, only: im8b
223 
224  use moda_msgcwd
225  use moda_bitbuf
226  use moda_tables
227 
228  implicit none
229 
230  integer, intent(in) :: lunin, lunot
231  integer, intent(out) :: iret
232  integer my_lunin, my_lunot, lin, lot, il, im, mest, icmp, nbyt, len0, len1, len2, len3, len4, l5, iok2cpy, bort_target_set
233 
234  ! Check for I8 integers
235 
236  if(im8b) then
237  im8b=.false.
238  call x84(lunin,my_lunin,1)
239  call x84(lunot,my_lunot,1)
240  call copysb(my_lunin,my_lunot,iret)
241  call x48(iret,iret,1)
242  im8b=.true.
243  return
244  endif
245 
246  ! If we're catching bort errors, set a target return location if one doesn't already exist.
247 
248  if (bort_target_set() == 1) then
249  call catch_bort_copysb_c(lunin,lunot,iret)
250  call bort_target_unset
251  return
252  endif
253 
254  iret = 0
255 
256  ! Check the file statuses
257 
258  call status(lunin,lin,il,im)
259  if(il==0) call bort('BUFRLIB: COPYSB - INPUT BUFR FILE IS CLOSED, IT MUST BE OPEN FOR INPUT')
260  if(il>0) call bort('BUFRLIB: COPYSB - INPUT BUFR FILE IS OPEN FOR OUTPUT, IT MUST BE OPEN FOR INPUT')
261  if(im==0) call bort('BUFRLIB: COPYSB - A MESSAGE MUST BE OPEN IN INPUT BUFR FILE, NONE ARE')
262 
263  if(lunot>0) then
264  call status(lunot,lot,il,im)
265  if(il==0) call bort('BUFRLIB: COPYSB - OUTPUT BUFR FILE IS CLOSED, IT MUST BE OPEN FOR OUTPUT')
266  if(il<0) call bort('BUFRLIB: COPYSB - OUTPUT BUFR FILE IS OPEN FOR INPUT, IT MUST BE OPEN FOR OUTPUT')
267  if(im==0) call bort('BUFRLIB: COPYSB - A MESSAGE MUST BE OPEN IN OUTPUT BUFR FILE, NONE ARE')
268  if( (inode(lin)/=inode(lot)) .and. ( (tag(inode(lin))/=tag(inode(lot))) .or. (iok2cpy(lin,lot)/=1) ) ) &
269  call bort('BUFRLIB: COPYSB - INPUT AND OUTPUT BUFR FILES MUST HAVE THE SAME INTERNAL TABLES, THEY ARE DIFFERENT HERE')
270  endif
271 
272  ! See if there is another subset in the message
273 
274  if(nsub(lin)==msub(lin)) then
275  iret = -1
276  return
277  endif
278 
279  ! Check compression status of input message, output message will match
280 
281  call mesgbc(-lunin, mest, icmp)
282 
283  if(icmp==1) then
284 
285  ! The input message is compressed, so read in the next subset and copy it as compressed to the output message.
286 
287  call readsb(lunin,iret)
288  if(lunot>0) then
289  call ufbcpy(lunin,lunot)
290  call cmpmsg('Y')
291  call writsb(lunot)
292  call cmpmsg('N')
293  endif
294  else
295 
296  ! The input message is uncompressed, so read in the next subset and copy it as uncompressed to the output message.
297 
298  ibit = (mbyt(lin))*8
299  call upb(nbyt,16,mbay(1,lin),ibit)
300  if (nbyt>65530) then
301  ! This is an oversized subset, so we can't rely on the value of nbyt as being the true size (in bytes) of the subset.
302  if ( (nsub(lin)==0) .and. (msub(lin)==1) ) then
303  ! But it's also the first and only subset in the message, so we can determine its true size in a different way.
304  call getlens(mbay(1,lin), 4, len0, len1, len2, len3, len4, l5)
305  nbyt = len4 - 4
306  else
307  ! We have no way to easily determine the true size of this oversized subset.
308  iret = -1
309  return
310  endif
311  endif
312  if(lunot>0) call cpyupd(lunot, lin, lot, nbyt)
313  mbyt(lin) = mbyt(lin) + nbyt
314  nsub(lin) = nsub(lin) + 1
315  endif
316 
317  return
318 end subroutine copysb
319 
335 recursive integer function icopysb(lunin,lunot) result(iret)
336 
337  use modv_vars, only: im8b
338 
339  implicit none
340 
341  integer, intent(in) :: lunin, lunot
342  integer my_lunin, my_lunot
343 
344  if(im8b) then
345  im8b=.false.
346  call x84(lunin,my_lunin,1)
347  call x84(lunot,my_lunot,1)
348  iret=icopysb(my_lunin,my_lunot)
349  im8b=.true.
350  return
351  endif
352 
353  call copysb(lunin,lunot,iret)
354 
355  return
356 end function icopysb
357 
376 integer function iok2cpy(lui,luo) result(iret)
377 
378  use moda_msgcwd
379  use moda_tables
380 
381  implicit none
382 
383  integer, intent(in) :: lui, luo
384  integer icmpdx, mtyp, msbt, inod, ntei, nteo, i
385 
386  character*8 subset
387 
388  iret = 0
389 
390  ! Do both logical units have the same internal table information?
391 
392  if ( icmpdx(lui,luo) == 1 ) then
393  iret = 1
394  return
395  endif
396 
397  ! No, so get the Table A mnemonic from the message to be copied, then check whether that mnemonic is defined within the
398  ! dictionary tables for the logical unit to be copied to.
399 
400  subset = tag(inode(lui))(1:8)
401  call nemtbax(luo,subset,mtyp,msbt,inod)
402  if ( inod == 0 ) return
403 
404  ! The Table A mnemonic is defined within the dictionary tables for both units, so now make sure the definitions are identical.
405 
406  ntei = isc(inode(lui))-inode(lui)
407  nteo = isc(inod)-inod
408  if ( ntei /= nteo ) return
409 
410  do i = 1, ntei
411  if ( tag(inode(lui)+i) /= tag(inod+i) ) return
412  if ( typ(inode(lui)+i) /= typ(inod+i) ) return
413  if ( isc(inode(lui)+i) /= isc(inod+i) ) return
414  if ( irf(inode(lui)+i) /= irf(inod+i) ) return
415  if ( ibt(inode(lui)+i) /= ibt(inod+i) ) return
416  enddo
417 
418  iret = 1
419 
420  return
421 end function iok2cpy
422 
455 recursive subroutine cpymem(lunot)
456 
457  use bufrlib
458 
459  use modv_vars, only: im8b
460 
461  use moda_msgcwd
462  use moda_bitbuf
463  use moda_msgmem
464  use moda_tables
465 
466  implicit none
467 
468  integer, intent(in) :: lunot
469  integer my_lunot, lin, lot, il, im, mtyp, msbt, inod, mbym, iupbs01, iok2cpy, bort_target_set
470 
471  character*8 subset
472 
473  ! Check for I8 integers
474 
475  if(im8b) then
476  im8b=.false.
477  call x84(lunot,my_lunot,1)
478  call cpymem(my_lunot)
479  im8b=.true.
480  return
481  endif
482 
483  ! If we're catching bort errors, set a target return location if one doesn't already exist.
484 
485  if (bort_target_set() == 1) then
486  call catch_bort_cpymem_c(lunot)
487  call bort_target_unset
488  return
489  endif
490 
491  ! Check the file statuses
492 
493  call status(munit,lin,il,im)
494  if(im==0) call bort('BUFRLIB: CPYMEM - A MESSAGE MUST BE OPEN IN INPUT BUFR MESSAGES IN INTERNAL MEMORY, NONE ARE')
495 
496  call status(lunot,lot,il,im)
497  if(il==0) call bort('BUFRLIB: CPYMEM - OUTPUT BUFR FILE IS CLOSED, IT MUST BE OPEN FOR OUTPUT')
498  if(il<0) call bort('BUFRLIB: CPYMEM - OUTPUT BUFR FILE IS OPEN FOR INPUT, IT MUST BE OPEN FOR OUTPUT')
499  if(im/=0) call bort('BUFRLIB: CPYMEM - ALL MESSAGES MUST BE CLOSED IN OUTPUT BUFR FILE, A MESSAGE IS OPEN')
500 
501  ! Make sure both files have the same tables
502 
503  subset = tag(inode(lin))(1:8)
504  call nemtba(lot,subset,mtyp,msbt,inod)
505  if(inode(lin)/=inod .and. iok2cpy(lin,lot)/=1) &
506  call bort('BUFRLIB: CPYMEM - INPUT BUFR MESSAGES IN INTERNAL MEMORY AND OUTPUT BUFR FILE MUST HAVE SAME INTERNAL '// &
507  'TABLES (DIFFERENT HERE)')
508 
509  ! Everything okay, so copy a message
510 
511  mbym = iupbs01(mbay(1,lin),'LENM')
512  call msgwrt(lunot,mbay(1,lin),mbym)
513 
514  ! Set the message control words for partition associated with lunot
515 
516  nmsg(lot) = nmsg(lot) + 1
517  nsub(lot) = msub(lin)
518  msub(lot) = msub(lin)
519  idate(lot) = idate(lin)
520  inode(lot) = inod
521 
522  return
523 end subroutine cpymem
524 
542 subroutine cpyupd(lunit,lin,lun,ibyt)
543 
544  use modv_vars, only: iprt, nby0, nby1, nby2, nby3
545 
546  use moda_msgcwd
547  use moda_bitbuf
548 
549  implicit none
550 
551  integer, intent(in) :: lunit, lin, lun, ibyt
552  integer lbit, lbyt, nbyt, iupb
553 
554  character*128 bort_str, errstr
555 
556  logical msgfull
557 
558  ! Check whether the new subset should be written into the currently open message
559 
560  if(msgfull(mbyt(lun),ibyt,maxbyt) .or. ((ibyt>65530).and.(nsub(lun)>0))) then
561  ! NO it should not, either because:
562  ! 1) it doesn't fit,
563  ! -- OR --
564  ! 2) it has byte count > 65530 (sufficiently close to the upper limit for the 16 bit byte counter placed at the
565  ! beginning of each subset), AND the current message has at least one subset in it,
566  ! SO write the current message out and create a new one to hold the current subset
567  call msgwrt(lunit,mbay(1,lun),mbyt(lun))
568  call msgini(lun)
569  endif
570 
571  if(msgfull(mbyt(lun),ibyt,maxbyt)) then
572  write(bort_str,'("BUFRLIB: CPYUPD - THE LENGTH OF THIS SUBSET EXCEEDS THE MAXIMUM MESSAGE LENGTH (",I6,")")') maxbyt
573  call bort(bort_str)
574  endif
575 
576  ! Transfer subset from one message to the other.
577 
578  ! Note that we want to append the data for this subset to the end of Section 4, but the value in mbyt(lun) already includes
579  ! the length of Section 5 (i.e. 4 bytes). Therefore, we need to begin writing at the point 3 bytes prior to the byte
580  ! currently pointed to by mbyt(lun).
581 
582  call mvb(mbay(1,lin),mbyt(lin)+1,mbay(1,lun),mbyt(lun)-3,ibyt)
583 
584  ! Update the subset and byte counters
585 
586  mbyt(lun) = mbyt(lun) + ibyt
587  nsub(lun) = nsub(lun) + 1
588 
589  lbit = (nby0+nby1+nby2+4)*8
590  call pkb(nsub(lun),16,mbay(1,lun),lbit)
591 
592  lbyt = nby0+nby1+nby2+nby3
593  nbyt = iupb(mbay(1,lun),lbyt+1,24)
594  lbit = lbyt*8
595  call pkb(nbyt+ibyt,24,mbay(1,lun),lbit)
596 
597  ! If the subset byte count is > 65530, then give it its own one-subset message (i.e. we cannot have any other subsets
598  ! in this message because their beginning would be beyond the upper limit of 65535 in the 16-bit byte counter, meaning
599  ! they could not be located!)
600 
601  if(ibyt>65530) then
602  if(iprt>=1) then
603  call errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
604  write ( unit=errstr, fmt='(A,I7,A,A)') 'BUFRLIB: CPYUPD - SUBSET HAS BYTE COUNT = ',ibyt,' > UPPER LIMIT OF 65535'
605  call errwrt(errstr)
606  call errwrt('>>>>>>>WILL BE COPIED INTO ITS OWN MESSAGE<<<<<<<<')
607  call errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
608  call errwrt(' ')
609  endif
610  call msgwrt(lunit,mbay(1,lun),mbyt(lun))
611  call msgini(lun)
612  endif
613 
614  return
615 end subroutine cpyupd
616 
639 recursive subroutine ufbcpy(lubin,lubot)
640 
641  use bufrlib
642 
643  use modv_vars, only: im8b
644 
645  use moda_usrint
646  use moda_msgcwd
647  use moda_ufbcpl
648  use moda_tables
649 
650  implicit none
651 
652  integer, intent(in) :: lubin, lubot
653  integer my_lubin, my_lubot, lui, luo, il, im, n, iok2cpy, bort_target_set
654 
655  ! Check for I8 integers
656 
657  if(im8b) then
658  im8b=.false.
659  call x84(lubin,my_lubin,1)
660  call x84(lubot,my_lubot,1)
661  call ufbcpy(my_lubin,my_lubot)
662  im8b=.true.
663  return
664  endif
665 
666  ! If we're catching bort errors, set a target return location if one doesn't already exist.
667 
668  if (bort_target_set() == 1) then
669  call catch_bort_ufbcpy_c(lubin,lubot)
670  call bort_target_unset
671  return
672  endif
673 
674  ! Check the file statuses and inode
675 
676  call status(lubin,lui,il,im)
677  if(il==0) call bort('BUFRLIB: UFBCPY - INPUT BUFR FILE IS CLOSED, IT MUST BE OPEN FOR INPUT')
678  if(il>0) call bort('BUFRLIB: UFBCPY - INPUT BUFR FILE IS OPEN FOR OUTPUT, IT MUST BE OPEN FOR INPUT')
679  if(im==0) call bort('BUFRLIB: UFBCPY - A MESSAGE MUST BE OPEN IN INPUT BUFR FILE, NONE ARE')
680  if(inode(lui)/=inv(1,lui)) &
681  call bort('BUFRLIB: UFBCPY - LOCATION OF INTERNAL TABLE FOR INPUT BUFR FILE DOES NOT AGREE WITH EXPECTED LOCATION '// &
682  'IN INTERNAL SUBSET ARRAY')
683 
684  call status(lubot,luo,il,im)
685  if(il==0) call bort('BUFRLIB: UFBCPY - OUTPUT BUFR FILE IS CLOSED, IT MUST BE OPEN FOR OUTPUT')
686  if(il<0) call bort('BUFRLIB: UFBCPY - OUTPUT BUFR FILE IS OPEN FOR INPUT, IT MUST BE OPEN FOR OUTPUT')
687  if(im==0) call bort('BUFRLIB: UFBCPY - A MESSAGE MUST BE OPEN IN OUTPUT BUFR FILE, NONE ARE')
688 
689  if( (inode(lui)/=inode(luo)) .and. ( (tag(inode(lui))/=tag(inode(luo))) .or. (iok2cpy(lui,luo)/=1) ) ) &
690  call bort('BUFRLIB: UFBCPY - INPUT AND OUTPUT BUFR FILES MUST HAVE THE SAME INTERNAL TABLES, THEY ARE DIFFERENT HERE')
691 
692  ! Everything okay, so copy user array from lui to luo
693 
694  nval(luo) = nval(lui)
695 
696  do n=1,nval(lui)
697  inv(n,luo) = inv(n,lui)
698  nrfelm(n,luo) = nrfelm(n,lui)
699  val(n,luo) = val(n,lui)
700  enddo
701 
702  luncpy(luo)=lubin
703 
704  return
705 end subroutine ufbcpy
706 
713 subroutine cpbfdx(lud,lun)
714 
715  use moda_msgcwd
716  use moda_tababd
717 
718  implicit none
719 
720  integer, intent(in) :: lud, lun
721  integer i
722 
723  ! Initialize the dictionary table partition
724 
725  call dxinit(lun,0)
726 
727  ! Positional index for Table A mnem.
728  inode(lun) = inode(lud)
729 
730  ntba(lun) = ntba(lud)
731  ntbb(lun) = ntbb(lud)
732  ntbd(lun) = ntbd(lud)
733 
734  ! Table A entries
735  do i=1,ntba(lud)
736  idna(i,lun,1) = idna(i,lud,1)
737  idna(i,lun,2) = idna(i,lud,2)
738  taba(i,lun) = taba(i,lud)
739  mtab(i,lun) = mtab(i,lud)
740  enddo
741 
742  ! Table B entries
743  do i=1,ntbb(lud)
744  idnb(i,lun) = idnb(i,lud)
745  tabb(i,lun) = tabb(i,lud)
746  enddo
747 
748  ! Copy Table D entries
749  do i=1,ntbd(lud)
750  idnd(i,lun) = idnd(i,lud)
751  tabd(i,lun) = tabd(i,lud)
752  enddo
753 
754  return
755 end subroutine cpbfdx
756 
766 subroutine mvb(ib1,nb1,ib2,nb2,nbm)
767 
768  implicit none
769 
770  integer, intent(in) :: ib1(*), nb1, nb2, nbm
771  integer, intent(out) :: ib2(*)
772  integer jb1, jb2, n, nval
773 
774  jb1 = 8*(nb1-1)
775  jb2 = 8*(nb2-1)
776 
777  do n=1,nbm
778  call upb(nval,8,ib1,jb1)
779  call pkb(nval,8,ib2,jb2)
780  enddo
781 
782  return
783 end subroutine mvb
784 
803 recursive subroutine ufbcup(lubin,lubot)
804 
805  use bufrlib
806 
807  use modv_vars, only: im8b
808 
809  use moda_usrint
810  use moda_msgcwd
811  use moda_tables
812  use moda_ivttmp
813 
814  implicit none
815 
816  integer, intent(in) :: lubin, lubot
817  integer my_lubin, my_lubot, lui, luo, il, im, ntag, ni, no, nv, nin, bort_target_set
818 
819  character*10 tago
820 
821  ! Check for I8 integers
822 
823  if(im8b) then
824  im8b=.false.
825  call x84(lubin,my_lubin,1)
826  call x84(lubot,my_lubot,1)
827  call ufbcup(my_lubin,my_lubot)
828  im8b=.true.
829  return
830  endif
831 
832  ! If we're catching bort errors, set a target return location if one doesn't already exist.
833 
834  if (bort_target_set() == 1) then
835  call catch_bort_ufbcup_c(lubin,lubot)
836  call bort_target_unset
837  return
838  endif
839 
840 
841  ! Check the file statuses and inode
842 
843  call status(lubin,lui,il,im)
844  if(il==0) call bort('BUFRLIB: UFBCUP - INPUT BUFR FILE IS CLOSED, IT MUST BE OPEN FOR INPUT')
845  if(il>0) call bort('BUFRLIB: UFBCUP - INPUT BUFR FILE IS OPEN FOR OUTPUT, IT MUST BE OPEN FOR INPUT')
846  if(im==0) call bort('BUFRLIB: UFBCUP - A MESSAGE MUST BE OPEN IN INPUT BUFR FILE, NONE ARE')
847  if(inode(lui)/=inv(1,lui)) call bort('BUFRLIB: UFBCUP - LOCATION OF INTERNAL TABLE FOR '// &
848  'INPUT BUFR FILE DOES NOT AGREE WITH EXPECTED LOCATION IN INTERNAL SUBSET ARRAY')
849 
850  call status(lubot,luo,il,im)
851  if(il==0) call bort('BUFRLIB: UFBCUP - OUTPUT BUFR FILE IS CLOSED, IT MUST BE OPEN FOR OUTPUT')
852  if(il<0) call bort('BUFRLIB: UFBCUP - OUTPUT BUFR FILE IS OPEN FOR INPUT, IT MUST BE OPEN FOR OUTPUT')
853  if(im==0) call bort('BUFRLIB: UFBCUP - A MESSAGE MUST BE OPEN IN OUTPUT BUFR FILE, NONE ARE')
854 
855  ! Make a list of unique tags in the input buffer
856 
857  ntag = 0
858 
859  outer1: do ni=1,nval(lui)
860  nin = inv(ni,lui)
861  if(itp(nin)>=2) then
862  do nv=1,ntag
863  if(ttmp(nv)==tag(nin)) cycle outer1
864  enddo
865  ntag = ntag+1
866  itmp(ntag) = ni
867  ttmp(ntag) = tag(nin)
868  endif
869  enddo outer1
870 
871  if(ntag==0) call bort('BUFRLIB: UFBCUP - THERE ARE NO ELEMENTS (TAGS) IN INPUT SUBSET BUFFER')
872 
873  ! Now, using the list of unique tags, make one copy of the common elements to the output buffer
874 
875  outer2: do nv=1,ntag
876  ni = itmp(nv)
877  do no=1,nval(luo)
878  tago = tag(inv(no,luo))
879  if(ttmp(nv)==tago) then
880  val(no,luo) = val(ni,lui)
881  cycle outer2
882  endif
883  enddo
884  enddo outer2
885 
886  return
887 end subroutine ufbcup
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
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 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
recursive subroutine cmpmsg(cf)
Specify whether BUFR messages output by future calls to message-writing subroutines and subset-writin...
Definition: compress.F90:33
integer function iok2cpy(lui, luo)
Check whether a BUFR message, or a data subset from within a BUFR message, can be copied from one For...
Definition: copydata.F90:377
recursive integer function icopysb(lunin, lunot)
Copy a BUFR data subset from one Fortran logical unit to another.
Definition: copydata.F90:336
subroutine cpbfdx(lud, lun)
Copy all of the DX BUFR table information from one unit to another within internal memory.
Definition: copydata.F90:714
subroutine mvb(ib1, nb1, ib2, nb2, nbm)
Copy a specified number of bytes from one packed binary array to another.
Definition: copydata.F90:767
recursive subroutine copybf(lunin, lunot)
Copy an entire BUFR file from one Fortran logical unit to another.
Definition: copydata.F90:23
recursive subroutine ufbcup(lubin, lubot)
Copy unique elements of a data subset.
Definition: copydata.F90:804
recursive subroutine copysb(lunin, lunot, iret)
Copy a BUFR data subset from one Fortran logical unit to another.
Definition: copydata.F90:219
subroutine cpyupd(lunit, lin, lun, ibyt)
Copy a BUFR data subset from one unit to another within internal memory.
Definition: copydata.F90:543
recursive subroutine cpymem(lunot)
Copy a BUFR message from internal arrays to a file.
Definition: copydata.F90:456
recursive subroutine ufbcpy(lubin, lubot)
Copy a BUFR data subset from one Fortran logical unit to another.
Definition: copydata.F90:640
recursive subroutine copymg(lunin, lunot)
Copy a BUFR message from one file to another.
Definition: copydata.F90:116
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 nemtbax(lun, nemo, mtyp, msbt, inod)
Get information about a Table A descriptor from the internal DX BUFR tables.
Definition: dxtable.F90:1194
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
subroutine errwrt(str)
Specify a custom location for the logging of error and diagnostic messages generated by the NCEPLIBS-...
Definition: errwrt.F90:32
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.
integer maxbyt
Maximum length of an output BUFR message.
Declare arrays which provide working space in several subprograms (usrtpl() and ufbcup()) which manip...
character *10, dimension(:), allocatable ttmp
tag array elements for new sections of a growing subset buffer.
integer, dimension(:), allocatable itmp
inv array elements for new sections of a growing subset buffer.
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 arrays and variables used to store the contents of one or more BUFR files within internal mem...
integer munit
Fortran logical unit number for use in accessing contents of BUFR files within internal memory.
Declare arrays and variables used to store DX BUFR tables internally for multiple file IDs.
integer, dimension(:), allocatable ntba
Number of Table A entries for each file ID (up to a maximum of maxtba, whose value is stored in array...
character *600, dimension(:,:), allocatable tabd
Table D entries for each file ID.
character *128, dimension(:,:), allocatable taba
Table A entries for each file ID.
integer, dimension(:,:), allocatable mtab
Entries within jump/link table corresponding to taba.
integer, dimension(:,:,:), allocatable idna
Message types (in array element 1) and subtypes (in array element 2) corresponding to taba.
integer, dimension(:), allocatable ntbd
Number of Table D entries for each file ID (up to a maximum of maxtbd, whose value is stored in array...
integer, dimension(:), allocatable ntbb
Number of Table B entries for each file ID (up to a maximum of maxtbb, whose value is stored in array...
integer, dimension(:,:), allocatable idnd
WMO bit-wise representations of the FXY values corresponding to tabd.
integer, dimension(:,:), allocatable idnb
WMO bit-wise representations of the FXY values corresponding to tabb.
character *128, dimension(:,:), allocatable tabb
Table B entries for each file ID.
Declare arrays and variables used to store the internal jump/link table.
integer, dimension(:), allocatable irf
Reference values corresponding to tag and typ:
integer, dimension(:), allocatable isc
Scale factors corresponding to tag and typ:
integer, dimension(:), allocatable ibt
Bit widths corresponding to tag and typ:
character *3, dimension(:), allocatable typ
Type indicators corresponding to tag:
character *10, dimension(:), allocatable tag
Mnemonics in the jump/link table.
integer, dimension(:), allocatable itp
Integer type values corresponding to typ:
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.
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.
real *8, dimension(:,:), allocatable, target val
Data values.
integer, dimension(:,:), allocatable, target inv
Inventory pointer which links each data value to its corresponding node in the internal jump/link tab...
integer, dimension(:,:), allocatable nrfelm
Referenced data value, for data values which refer to a previous data value in the BUFR data subset v...
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...
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.
subroutine rdmsgw(lunit, mesg, iret)
Read the next BUFR message from logical unit lunit as an array of integer words.
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...
recursive subroutine writsb(lunit)
Write a complete data subset into a BUFR message, for eventual output to logical unit lunit.
recursive subroutine readsb(lunit, iret)
Read the next data subset from a BUFR message.
Definition: readwritesb.F90:32
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 mesgbc(lunin, mesgtyp, icomp)
Return the message type (from Section 1) and message compression indicator (from Section 3) of a BUFR...
Definition: s013vals.F90:1541
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