Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose more of the new file-based API in Fortran #786

Merged
merged 13 commits into from
Dec 23, 2024
21 changes: 20 additions & 1 deletion src/g2c_interface.F90
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,25 @@ function g2c_open_index(data_file, index_file, mode, g2cid) bind(c)
integer(c_int) :: g2c_open_index
end function g2c_open_index

! int g2c_inq(int g2cid, int *num_msg);
function g2c_inq(g2id, num_msg) bind(c)
use iso_c_binding
integer(c_int), value :: g2id
integer(c_int), intent(out) :: num_msg
integer(c_int) :: g2c_inq
end function g2c_inq

function g2c_inq_msg(g2id, msg_num, discipline, num_fields, &
num_local, center, subcenter, master_version, local_version) bind(c)
use iso_c_binding
integer(c_int), value :: g2id
integer(c_int), value :: msg_num
integer(c_signed_char), intent(out) :: discipline
integer(c_int), intent(out) :: num_fields, num_local
integer(c_short), intent(out) :: center, subcenter
integer(c_signed_char), intent(out) :: master_version, local_version
integer(c_int) :: g2c_inq_msg
end function g2c_inq_msg

! int g2c_inq_msg(int g2cid, int msg_num, unsigned char *discipline, int *num_fields,
! int *num_local, short *center, short *subcenter, unsigned char *master_version,
! unsigned char *local_version);
Expand All @@ -32,6 +50,7 @@ function g2c_close(g2id) bind(c)
integer(c_int), value :: g2id
integer(c_int) :: g2c_close
end function g2c_close

function g2c_set_log_level(log_level) bind(c)
use iso_c_binding
integer(c_int), intent(in) :: log_level
Expand Down
75 changes: 75 additions & 0 deletions src/g2cf.F90
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,81 @@ function g2cf_open_index(data_file, index_file, mode, g2cid) result (status)
status = cstatus
end function g2cf_open_index

!> Learn how many messages are in a GRIB2 file.
!>
!> @param g2id The ID of the open file
!> @param num_msg The number of messages in the file.
!>
!> @return 0 for success, error code otherwise.
!>
!> @author Edward Hartnett @date 2024-12-21
function g2cf_inq(g2id, num_msg) result(status)
use iso_c_binding
use g2c_interface
implicit none

integer, intent(in) :: g2id
integer, intent(out) :: num_msg
integer :: status

integer(c_int) :: cg2id, cnum_msg, cstatus

cg2id = g2id
cstatus = g2c_inq(cg2id, cnum_msg)
num_msg = cnum_msg
status = cstatus
end function g2cf_inq

!> Learn about a message are in a GRIB2 file.
!>
!> @param[in] g2id The ID of the open file
!> @param[in] msg_num The number of message to learn about. The
!> first message in the file is number 1.
!> @param[out] discipline The discipline of the message.
!> @param[out] num_fields Number of fields in the message.
!> @param[out] num_local Number of local sections in the message.
!> @param[out] center Originating center.
!> @param[out] subcenter Originating sub-center.
!> @param[out] master_version Master version.
!> @param[out] local_version Local version.
!>
!> @return 0 for success, error code otherwise.
!>
!> @author Edward Hartnett @date 2024-12-21
function g2cf_inq_msg(g2id, msg_num, discipline, num_fields, &
num_local, center, subcenter, master_version, local_version) result(status)
use iso_c_binding
use g2c_interface
implicit none

integer, intent(in) :: g2id, msg_num
integer(kind = 1), intent(out) :: discipline
integer, intent(out) :: num_fields, num_local
integer(kind = 2), intent(out) :: center, subcenter
integer(kind = 1), intent(out) :: master_version, local_version
integer :: status

integer(c_int) :: cg2id, cmsg_num, cstatus
integer(c_signed_char) :: cdiscipline
integer(c_int) :: cnum_fields, cnum_local
integer(c_short) :: ccenter, csubcenter
integer(c_signed_char) :: cmaster_version, clocal_version

cg2id = g2id
! Subtract 1 because C is zero-based.
cmsg_num = msg_num - 1
cstatus = g2c_inq_msg(cg2id, cmsg_num, cdiscipline, cnum_fields, &
cnum_local, ccenter, csubcenter, cmaster_version, clocal_version)
discipline = cdiscipline
num_fields = cnum_fields
num_local = cnum_local
center = ccenter
subcenter = csubcenter
master_version = cmaster_version
local_version = clocal_version
status = cstatus
end function g2cf_inq_msg

!> Close a GRIB2 file.
!>
!> @param g2id The ID of the open file
Expand Down
22 changes: 12 additions & 10 deletions tests/test_g2cf.F90
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,24 @@ program test_g2cf
integer :: ierr

print *, 'Testing g2cf API...'
ierr = g2cf_set_log_level(1)
!ierr = g2cf_set_log_level(1)

! Open the test file.
ierr = g2cf_open(fileName, 0, g2cid)
if (ierr .ne. 0) stop 2

! ! Check number of messages.
! ierr = g2cf_inq(g2cid, num_msg)
! if (ierr .ne. 0) stop 10
! if (num_msg .ne. 19) stop 11
! Check number of messages.
ierr = g2cf_inq(g2cid, num_msg)
if (ierr .ne. 0) stop 10
if (num_msg .ne. 19) stop 11

! ! Check the last message.
! ierr = g2cf_inq_msg(g2cid, 19, discipline, num_fields, num_local, center, subcenter, &
! master_version, local_version)
! if (discipline .ne. 10 .or. num_fields .ne. 1 .or. num_local .ne. 0 .or. center .ne. 7 .or. &
! subcenter .ne. 0 .or. master_version .ne. 2 .or. local_version .ne. 1) stop 12
! Check the last message.
ierr = g2cf_inq_msg(g2cid, 19, discipline, num_fields, num_local, center, subcenter, &
master_version, local_version)
if (ierr .ne. 0) stop 100
!print *, discipline, num_fields, num_local, center, subcenter, master_version, local_version
if (discipline .ne. 10 .or. num_fields .ne. 1 .or. num_local .ne. 0 .or. center .ne. 7 .or. &
subcenter .ne. 0 .or. master_version .ne. 2 .or. local_version .ne. 1) stop 12

! Close the file.
ierr = g2cf_close(g2cid)
Expand Down
Loading