NCEPLIBS-bufr  12.3.0
ciencode.F90
Go to the documentation of this file.
1 
5 
24 subroutine pkc(chr,nchr,ibay,ibit)
25 
26  use modv_vars, only: nbitw, nbytw, iordle, iordbe
27 
28  implicit none
29 
30  character*(*), intent(in) :: chr
31  character*1 cval(8)
32 
33  integer, intent(in) :: nchr
34  integer, intent(out) :: ibay(*)
35  integer, intent(inout) :: ibit
36  integer ival(2), lb, i, nwd, nbt, nbit, int, msk, irev
37 
38  equivalence(cval,ival)
39 
40  ! Set lb to point to the "low-order" (i.e. least significant) byte within a machine word.
41 
42 #ifdef BIG_ENDIAN
43  lb = iordbe(nbytw)
44 #else
45  lb = iordle(nbytw)
46 #endif
47 
48  ival(1) = 0
49  nbit = 8
50 
51  do i=1,nchr
52  if(i<=len(chr)) then
53  cval(lb) = chr(i:i)
54  else
55  cval(lb) = ' '
56  endif
57 
58  nwd = ibit/nbitw + 1
59  nbt = mod(ibit,nbitw)
60  int = ishft(ival(1),nbitw-nbit)
61  int = ishft(int,-nbt)
62  msk = ishft( -1,nbitw-nbit)
63  msk = ishft(msk,-nbt)
64  ibay(nwd) = irev(ior(iand(irev(ibay(nwd)),not(msk)),int))
65  if(nbt+nbit>nbitw) then
66 
67  ! This character will not fit within the current word (i.e. array member) of ibay, because there
68  ! are less than 8 bits of space left. Store as many bits as will fit within the current
69  ! word and then store the remaining bits within the next word.
70 
71  int = ishft(ival(1),2*nbitw-(nbt+nbit))
72  msk = ishft( -1,2*nbitw-(nbt+nbit))
73  ibay(nwd+1) = irev(ior(iand(irev(ibay(nwd+1)),not(msk)),int))
74  endif
75  ibit = ibit + nbit
76  enddo
77 
78  return
79 end subroutine pkc
80 
96 subroutine pkb8(nval,nbits,ibay,ibit)
97 
98  use modv_vars, only: nbitw
99 
100  implicit none
101 
102  integer*8, intent(in) :: nval
103  integer, intent(in) :: nbits
104  integer, intent(out) :: ibay(*)
105  integer, intent(inout) :: ibit
106 
107  integer*8 :: nval8
108  integer :: nval4, nvals(2)
109 
110  equivalence(nval8,nvals)
111 
112  if(nbits<0) call bort('bufrlib: pkb8 - nbits < zero !!!!!')
113  if(nbits>64) call bort('bufrlib: pkb8 - nbits > 64 !!!!!')
114 
115  nval8=nval
116  nval4=nvals(2)
117  call pkb(nval4,max(nbits-nbitw,0),ibay,ibit)
118  nval4=nvals(1)
119  call pkb(nval4,min(nbits,nbitw),ibay,ibit)
120 
121  return
122 end subroutine pkb8
123 
139 subroutine pkb(nval,nbits,ibay,ibit)
140 
141  use modv_vars, only: nbitw
142 
143  implicit none
144 
145  integer, intent(in) :: nval, nbits
146  integer, intent(out) :: ibay(*)
147  integer, intent(inout) :: ibit
148  integer nwd, nbt, ival, int, msk, irev
149 
150  character*156 bort_str
151 
152  if(nbits>nbitw) then
153  write(bort_str,'("BUFRLIB: PKB - NUMBER OF BITS BEING PACKED '// &
154  ', NBITS (",I4,"), IS > THE INTEGER WORD LENGTH ON THIS MACHINE, NBITW (",I3,")")') nbits,nbitw
155  call bort(bort_str)
156  endif
157 
158  nwd = ibit/nbitw + 1
159  nbt = mod(ibit,nbitw)
160  ival = nval
161  if(ishft(ival,-nbits)>0) ival = -1
162  int = ishft(ival,nbitw-nbits)
163  int = ishft(int,-nbt)
164  msk = ishft(-1,nbitw-nbits)
165  msk = ishft(msk,-nbt)
166  ibay(nwd) = irev(ior(iand(irev(ibay(nwd)),not(msk)),int))
167  if(nbt+nbits>nbitw) then
168 
169  ! There are less than nbits bits remaining within the current word (i.e. array member) of ibay,
170  ! so store as many bits as will fit within the current word and then store the remaining bits
171  ! within the next word.
172 
173  int = ishft(ival,2*nbitw-(nbt+nbits))
174  msk = ishft( -1,2*nbitw-(nbt+nbits))
175  ibay(nwd+1) = irev(ior(iand(irev(ibay(nwd+1)),not(msk)),int))
176  endif
177 
178  ibit = ibit + nbits
179 
180  return
181 end subroutine pkb
182 
193 recursive subroutine ipkm(cbay,nbyt,n)
194 
195  use bufrlib
196 
197  use modv_vars, only: im8b, nbytw
198 
199  implicit none
200 
201  integer, intent(in) :: n, nbyt
202  integer my_n, my_nbyt, int, irev, i, bort_target_set
203 
204  character*(*), intent(out) :: cbay
205  character*128 bort_str
206  character*4 cint
207  character*5 ccbay
208 
209  equivalence(cint,int)
210 
211  ! Check for I8 integers.
212 
213  if(im8b) then
214  im8b=.false.
215  call x84(n,my_n,1)
216  call x84(nbyt,my_nbyt,1)
217  call ipkm(cbay,my_nbyt,my_n)
218  im8b=.true.
219  return
220  endif
221 
222  ! If we're catching bort errors, set a target return location if one doesn't already exist.
223 
224  if (bort_target_set() == 1) then
225  call catch_bort_ipkm_c(ccbay,nbyt,n,len(ccbay))
226  cbay(1:nbyt) = ccbay(1:nbyt)
227  call bort_target_unset
228  return
229  endif
230 
231  if(nbyt>nbytw) then
232  write(bort_str,'("BUFRLIB: IPKM - NUMBER OF BYTES BEING PACKED '// &
233  ', NBYT (",I4,"), IS > THE INTEGER WORD LENGTH ON THIS MACHINE, NBYTW (",I3,")")') nbyt,nbytw
234  call bort(bort_str)
235  endif
236 
237  int = irev(ishft(n,(nbytw-nbyt)*8))
238  do i=1,nbyt
239  cbay(i:i) = cint(i:i)
240  enddo
241 
242  return
243 end subroutine ipkm
244 
261 integer*8 function ipks(val,node) result(i8ret)
262 
263  use moda_tables
264  use moda_nrv203
265 
266  implicit none
267 
268  integer*8 imask
269  integer, intent(in) :: node
270  integer jj
271 
272  real*8, parameter :: ten = 10.
273  real*8, intent(in) :: val
274 
275  i8ret = nint(val * ten**isc(node),8) - irf(node)
276 
277  if ( nnrv > 0 ) then
278  ! There are redefined reference values in the jump/link table, so we need to check if this node is affected by any of them.
279  do jj = 1, nnrv
280  if ( node == inodnrv(jj) ) then
281  ! This node contains a redefined reference value. Per the rules of BUFR, negative values should be encoded as positive
282  ! integers with the left-most bit set to 1.
283  nrv(jj) = nint(val)
284  if ( nrv(jj) < 0 ) then
285  imask = 2_8**(ibt(node)-1)
286  i8ret = ior(abs(nrv(jj)),imask)
287  else
288  i8ret = nrv(jj)
289  end if
290  return
291  else if ( ( tag(node)(1:8) == tagnrv(jj) ) .and. ( node >= isnrv(jj) ) .and. ( node <= ienrv(jj) ) ) then
292  ! The corresponding redefinded reference value needs to be used when encoding this value.
293  i8ret = nint(val * ten**isc(node),8) - nrv(jj)
294  return
295  end if
296  end do
297  end if
298 
299  return
300 end function ipks
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 pkc(chr, nchr, ibay, ibit)
Encode a character string within a specified number of bytes of an integer array, starting at the bit...
Definition: ciencode.F90:25
integer *8 function ipks(val, node)
Pack a real*8 value into an integer by applying the proper scale and reference values.
Definition: ciencode.F90:262
recursive subroutine ipkm(cbay, nbyt, n)
Encode an integer value within a specified number of bytes of a character string, up to a maximum of ...
Definition: ciencode.F90:194
subroutine pkb(nval, nbits, ibay, ibit)
Encode an integer value within a specified number of bits of an integer array, starting at the bit im...
Definition: ciencode.F90:140
subroutine pkb8(nval, nbits, ibay, ibit)
Encode an 8-byte integer value within a specified number of bits of an integer array,...
Definition: ciencode.F90:97
integer function irev(n)
Return a copy of an integer value with the bytes possibly reversed.
Definition: misc.F90:236
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 for use with any 2-03-YYY (change reference value) operators present wit...
integer, dimension(:), allocatable ienrv
End of entry range in jump/link table, within which the corresponding new reference value in nrv will...
character *8, dimension(:), allocatable tagnrv
Table B mnemonic to which the corresponding new reference value in nrv applies.
integer, dimension(:), allocatable isnrv
Start of entry range in jump/link table, within which the corresponding new reference value in nrv wi...
integer nnrv
Number of entries in the jump/link table which contain new reference values (up to a maximum of mxnrv...
integer *8, dimension(:), allocatable nrv
New reference values corresponding to inodnrv.
integer, dimension(:), allocatable inodnrv
Entries within jump/link table which contain new reference values.
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 *10, dimension(:), allocatable tag
Mnemonics in the jump/link table.
subroutine x84(iin8, iout4, nval)
Encode one or more 8-byte integer values as 4-byte integer values.
Definition: x4884.F90:65