Skip to content

Commit

Permalink
Merge pull request #519 from NOAA-EMC/feature/expose_readlc_c
Browse files Browse the repository at this point in the history
Feature/expose readlc c
  • Loading branch information
jbathegit authored Aug 30, 2023
2 parents d3a5747 + bdddb02 commit 889bc4b
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 4 deletions.
26 changes: 25 additions & 1 deletion src/bufr_c2f_interface.F90
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ module bufr_c2f_interface
public :: ufbint_c, ufbrep_c, ufbseq_c
public :: mtinfo_c, bvers_c, status_c, ibfms_c
public :: get_isc_c, get_link_c, get_itp_c, get_typ_c, get_tag_c, get_jmpb_c
public :: get_inode_c, get_nval_c, get_val_c, get_inv_c, get_irf_c
public :: get_inode_c, get_nval_c, get_val_c, get_inv_c, get_irf_c, readlc_c
public :: delete_table_data_c
public :: iupbs01_c, iupb_c, imrkopr_c, istdesc_c, ifxy_c
public :: igetntbi_c, igettdi_c, stntbi_c
Expand Down Expand Up @@ -587,6 +587,30 @@ subroutine get_inv_c(lun, inv_ptr, inv_size) bind(C, name='get_inv_f')
inv_ptr = c_loc(inv(1, lun))
end subroutine get_inv_c

!> Function used to get long strings from the BUFR file.
!>
!> @param lunit - Fortran logical unit.
!> @param str_id - Mnemonic for the string for the source field plus the index number
!> (ex: 'IDMN#2')
!> @param output_str - The pre-allocated result string
!> @param output_str_len - Size of the result string buffer
!>
!> @author Ronald McLaren @date 2023-07-03
subroutine readlc_c(lunit, str_id, output_str, output_str_len) bind(C, name='readlc_f')
use moda_rlccmn
integer(c_int), value, intent(in) :: lunit
character(kind=c_char, len=1), intent(in) :: str_id(*)
character(kind=c_char, len=1), intent(out) :: output_str(*)
integer(c_int), intent(in), value :: output_str_len

character(len=120) :: output_str_f
integer :: output_str_len_f

call readlc(lunit, output_str_f, c_f_string(str_id))
output_str_len_f = len(trim(output_str_f)) + 1 ! add 1 for the null terminator
call copy_f_c_str(output_str_f, output_str, min(output_str_len_f, output_str_len))
end subroutine readlc_c

!> Deletes the copies of the moda_tables arrays.
!>
!> @author Ronald McLaren @date 2022-03-23
Expand Down
14 changes: 14 additions & 0 deletions src/bufr_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,20 @@ extern "C" {
*/
void get_inv_f(int lun, int** inv_ptr, int* inv_size);

/**
* Function used to get long strings from the BUFR file.
*
* @param lunit - Fortran logical unit.
* @param str_id - Mnemonic for the string for the source field plus the index number
* (ex: 'IDMN#2')
* @param output_str - The pre-allocated result string
* @param output_str_len - Size of the result string buffer
*
* @author Ronald McLaren @date 2023-07-03
*/

void readlc_f(int lunit, const char* str_id, char* output_str, int output_str_len);

/**
* Deletes the copies of the moda_tables arrays.
*
Expand Down
52 changes: 49 additions & 3 deletions test/test_c_interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ static const int BUFR_FILE_UNIT = 12;
static const int SUBSET_STRING_LEN = 10;

static const char* INPUT_FILE = "testfiles/data/1bamua";
static const char* INPUT_FILE_LONG_STR = "testfiles/OUT_10";


// Supporting functions

unsigned int countSubsets(const char* subset)
unsigned int countSubsets(const char* filePath, const char* subset)
{
open_f(BUFR_FILE_UNIT, INPUT_FILE);
open_f(BUFR_FILE_UNIT, filePath);
openbf_f(BUFR_FILE_UNIT, "IN", BUFR_FILE_UNIT);

int iddate;
Expand Down Expand Up @@ -58,7 +59,7 @@ void test_basicInterface()
int iret;
int iddate;
char msg_subset[SUBSET_STRING_LEN];
unsigned int subset_cnt = countSubsets(subset);
unsigned int subset_cnt = countSubsets(INPUT_FILE, subset);
unsigned int idx;

open_f(BUFR_FILE_UNIT, INPUT_FILE);
Expand Down Expand Up @@ -112,6 +113,50 @@ void test_basicInterface()
close_f(BUFR_FILE_UNIT);
}

void test_longStrings()
{
static const int LONG_STR_LEN = 120;
const char* mnemonic = "SOFTV";

int iddate;
char msg_subset[SUBSET_STRING_LEN];

open_f(BUFR_FILE_UNIT, INPUT_FILE_LONG_STR);
openbf_f(BUFR_FILE_UNIT, "IN", BUFR_FILE_UNIT);

int bufrLoc;
int il, im; // throw away

char long_str[LONG_STR_LEN];

int subset_idx = 0;
while (ireadmg_f(BUFR_FILE_UNIT, msg_subset, &iddate, SUBSET_STRING_LEN) == 0)
{
while ((ireadsb_f(BUFR_FILE_UNIT) == 0) && (subset_idx < MAX_SUBSETS))
{
status_f(BUFR_FILE_UNIT, &bufrLoc, &il, &im);
readlc_f(BUFR_FILE_UNIT, mnemonic, long_str, LONG_STR_LEN);
break;
}
break;
}

if (strlen(long_str) != 11)
{
printf("%s", "Didn't read the correct long string length for SOFTV.");
exit(1);
}

if (strncmp(long_str, "MW41 2.17.0", 11) != 0)
{
printf("%s", "Didn't read the correct long string for SOFTV.");
exit(1);
}

closbf_f(BUFR_FILE_UNIT);
close_f(BUFR_FILE_UNIT);
}


int cIdx(int fortranIdx)
{
Expand Down Expand Up @@ -478,6 +523,7 @@ void test_getTypeInfo()
int main()
{
test_basicInterface();
test_longStrings();
test_intrusiveInterface();
test_getTypeInfo();

Expand Down

0 comments on commit 889bc4b

Please sign in to comment.