Encode a bits stream (must be multiple of 24 bits) into base64 charcaters code (of length multiple of 4).
The bits stream are encoded in chunks of 24 bits as the following example (in little endian order)
+--first octet--+-second octet--+--third octet--+ |7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0| +-----------+---+-------+-------+---+-----------+ |5 4 3 2 1 0|5 4 3 2 1 0|5 4 3 2 1 0|5 4 3 2 1 0| +--1.index--+--2.index--+--3.index--+--4.index--+
The 4 indexes are stored into 4 elements 8 bits array, thus 2 bits of each array element are not used.
The number of paddings must be computed outside this procedure, into the calling scope.
This procedure is the backend of encoding, thus it must be never called outside the module.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer(kind=I1P), | intent(in) | :: | bits(1:) | Bits to be encoded. |
||
| integer(kind=I4P), | intent(in) | :: | padd | Number of padding characters ('='). |
||
| character(len=*), | intent(out) | :: | code | Characters code. |
Nodes of different colours represent the following:
Solid arrows point from a procedure to one which it calls. Dashed arrows point from an interface to procedures which implement that interface. This could include the module procedures in a generic interface or the implementation in a submodule of an interface in a parent module.
pure subroutine encode_bits(bits, padd, code)
!---------------------------------------------------------------------------------------------------------------------------------
!< Encode a bits stream (must be multiple of 24 bits) into base64 charcaters code (of length multiple of 4).
!<
!< The bits stream are encoded in chunks of 24 bits as the following example (in little endian order)
!<```
!< +--first octet--+-second octet--+--third octet--+
!< |7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|
!< +-----------+---+-------+-------+---+-----------+
!< |5 4 3 2 1 0|5 4 3 2 1 0|5 4 3 2 1 0|5 4 3 2 1 0|
!< +--1.index--+--2.index--+--3.index--+--4.index--+
!<```
!< @note The 4 indexes are stored into 4 elements 8 bits array, thus 2 bits of each array element are not used.
!<
!< @note The number of paddings must be computed outside this procedure, into the calling scope.
!<
!< @warning This procedure is the backend of encoding, thus it must be never called outside the module.
!---------------------------------------------------------------------------------------------------------------------------------
integer(I1P), intent(in) :: bits(1:) !< Bits to be encoded.
integer(I4P), intent(in) :: padd !< Number of padding characters ('=').
character(*), intent(out) :: code !< Characters code.
integer(I1P) :: sixb(1:4) !< 6 bits slices (stored into 8 bits integer) of 24 bits input.
integer(I8P) :: c !< Counter.
integer(I8P) :: e !< Counter.
integer(I8P) :: Nb !< Length of bits array.
!---------------------------------------------------------------------------------------------------------------------------------
!---------------------------------------------------------------------------------------------------------------------------------
Nb=size(bits,dim=1,kind=I8P)
c = 1_I8P
do e=1_I8P,Nb,3_I8P ! loop over array elements: 3 bytes (24 bits) scanning
sixb = 0_I1P
call mvbits(bits(e ),2,6,sixb(1),0)
call mvbits(bits(e ),0,2,sixb(2),4)
if (e+1<=Nb) then
call mvbits(bits(e+1),4,4,sixb(2),0)
call mvbits(bits(e+1),0,4,sixb(3),2)
endif
if (e+2<=Nb) then
call mvbits(bits(e+2),6,2,sixb(3),0)
call mvbits(bits(e+2),0,6,sixb(4),0)
endif
sixb = sixb + 1_I1P
code(c :c ) = base64(sixb(1):sixb(1))
code(c+1:c+1) = base64(sixb(2):sixb(2))
code(c+2:c+2) = base64(sixb(3):sixb(3))
code(c+3:c+3) = base64(sixb(4):sixb(4))
c = c + 4_I8P
enddo
if (padd>0) code(len(code)-padd+1:)=repeat('=',padd)
return
!---------------------------------------------------------------------------------------------------------------------------------
endsubroutine encode_bits