|
7 | 7 | ! |
8 | 8 | module mpas_io |
9 | 9 |
|
| 10 | +#define IO_DEBUG_WRITE(M, ARGS) !call mpas_log_write(M, ARGS) |
| 11 | +#define IO_ERROR_WRITE(M, ARGS) call mpas_log_write( M, ARGS, messageType=MPAS_LOG_ERR) |
| 12 | + |
10 | 13 | use mpas_derived_types |
11 | 14 | use mpas_attlist |
12 | 15 | use mpas_dmpar |
@@ -1847,6 +1850,13 @@ subroutine MPAS_io_get_var_generic(handle, fieldname, intVal, intArray1d, intArr |
1847 | 1850 | character (len=:), pointer :: charVal_p |
1848 | 1851 | character (len=:), dimension(:), pointer :: charArray1d_p |
1849 | 1852 |
|
| 1853 | + ! local variables returned from MPAS_io_inq_var |
| 1854 | + integer :: fieldtype |
| 1855 | + integer :: ndims |
| 1856 | + integer, dimension(:), pointer :: dimsizes |
| 1857 | + character (len=StrKIND), dimension(:), pointer :: dimnames |
| 1858 | + character (len=StrKIND) :: message |
| 1859 | + |
1850 | 1860 | #ifdef MPAS_SMIOL_SUPPORT |
1851 | 1861 | type (SMIOLf_decomp), pointer :: null_decomp |
1852 | 1862 |
|
@@ -1984,22 +1994,41 @@ subroutine MPAS_io_get_var_generic(handle, fieldname, intVal, intArray1d, intArr |
1984 | 1994 | ! call mpas_log_write(' value is char') |
1985 | 1995 |
|
1986 | 1996 | charVal_p => charVal |
| 1997 | + |
| 1998 | + ! get the dimension of the char variable to ensure the provided output buffer is large enough |
| 1999 | + call MPAS_io_inq_var(handle, fieldname, fieldtype, ndims, dimnames, dimsizes, local_ierr) |
| 2000 | + do i = 1, ndims |
| 2001 | + message = ' MPAS_io_get_var_generic len(charVal):$i var "'//trim(fieldname)// & |
| 2002 | + '" type is $i dim is $i '// trim(dimnames(i))//' size is $i' |
| 2003 | + IO_DEBUG_WRITE(message, intArgs=(/len(charVal), fieldtype, i, dimsizes(i)/)) |
| 2004 | + end do |
| 2005 | + ! because charVal is provided, assume dimension 1 is the string length |
| 2006 | + if (dimsizes(1) > len(charVal)) then |
| 2007 | + local_ierr = MPAS_IO_ERR_INSUFFICIENT_BUF |
| 2008 | + message = 'Length of string variable "'//trim(fieldname)//'" in file "'//trim(handle % filename)//'"' |
| 2009 | + IO_ERROR_WRITE(message, intArgs=[0]) |
| 2010 | + message = ' exceeds buffer size: len('//trim(fieldname)//')=$i, len(buffer)=$i' |
| 2011 | + IO_ERROR_WRITE(message, intArgs=(/dimsizes(1), len(charVal)/)) |
| 2012 | + else |
1987 | 2013 | #ifdef MPAS_SMIOL_SUPPORT |
1988 | | - local_ierr = SMIOLf_get_var(handle % smiol_file, trim(fieldname), null_decomp, charVal_p) |
| 2014 | + local_ierr = SMIOLf_get_var(handle % smiol_file, trim(fieldname), null_decomp, charVal_p) |
1989 | 2015 | #endif |
1990 | 2016 |
|
1991 | 2017 | #ifdef MPAS_PIO_SUPPORT |
1992 | | - if (field_cursor % fieldhandle % has_unlimited_dim) then |
1993 | | - count2(1) = field_cursor % fieldhandle % dims(1) % dimsize |
1994 | | - pio_ierr = PIO_get_var(handle % pio_file, field_cursor % fieldhandle % fieldid, start2, count2, tempchar) |
1995 | | - charVal(1:count2(1)) = tempchar(1)(1:count2(1)) |
1996 | | - else |
1997 | | - start1(1) = 1 |
1998 | | - count1(1) = field_cursor % fieldhandle % dims(1) % dimsize |
1999 | | - pio_ierr = PIO_get_var(handle % pio_file, field_cursor % fieldhandle % fieldid, start1, count1, tempchar) |
2000 | | - charVal(1:count1(1)) = tempchar(1)(1:count1(1)) |
2001 | | - end if |
| 2018 | + if (field_cursor % fieldhandle % has_unlimited_dim) then |
| 2019 | + count2(1) = field_cursor % fieldhandle % dims(1) % dimsize |
| 2020 | + pio_ierr = PIO_get_var(handle % pio_file, field_cursor % fieldhandle % fieldid, start2, count2, tempchar) |
| 2021 | + charVal(1:count2(1)) = tempchar(1)(1:count2(1)) |
| 2022 | + else |
| 2023 | + start1(1) = 1 |
| 2024 | + count1(1) = field_cursor % fieldhandle % dims(1) % dimsize |
| 2025 | + pio_ierr = PIO_get_var(handle % pio_file, field_cursor % fieldhandle % fieldid, start1, count1, tempchar) |
| 2026 | + charVal(1:count1(1)) = tempchar(1)(1:count1(1)) |
| 2027 | + end if |
2002 | 2028 | #endif |
| 2029 | + end if |
| 2030 | + deallocate(dimsizes) |
| 2031 | + deallocate(dimnames) |
2003 | 2032 | else if (present(charArray1d)) then |
2004 | 2033 | ! call mpas_log_write(' value is char1') |
2005 | 2034 | #ifdef MPAS_PIO_SUPPORT |
@@ -2765,6 +2794,13 @@ subroutine MPAS_io_get_var_generic(handle, fieldname, intVal, intArray1d, intArr |
2765 | 2794 | end if |
2766 | 2795 |
|
2767 | 2796 | ! call mpas_log_write('Checking for error') |
| 2797 | + if (local_ierr == MPAS_IO_ERR_INSUFFICIENT_BUF) then |
| 2798 | + call MPAS_io_err_mesg(handle % ioContext, local_ierr, .false.) |
| 2799 | + io_global_err = local_ierr |
| 2800 | + if (present(ierr)) ierr = local_ierr |
| 2801 | + return |
| 2802 | + endif |
| 2803 | + |
2768 | 2804 | #ifdef MPAS_PIO_SUPPORT |
2769 | 2805 | if (pio_ierr /= PIO_noerr) then |
2770 | 2806 | io_global_err = pio_ierr |
@@ -6498,6 +6534,10 @@ subroutine MPAS_io_err_mesg(ioContext, ierr, fatal) |
6498 | 6534 | call mpas_log_write('MPAS IO Error: Would clobber existing file', MPAS_LOG_ERR) |
6499 | 6535 | case (MPAS_IO_ERR_NOEXIST_READ) |
6500 | 6536 | call mpas_log_write('MPAS IO Error: Attempting to read a file which does not exist.', MPAS_LOG_ERR) |
| 6537 | + case (MPAS_IO_ERR_MISSING_DIM) |
| 6538 | + call mpas_log_write('MPAS IO Error: Attempting to read a dimension which does not exist.', MPAS_LOG_ERR) |
| 6539 | + case (MPAS_IO_ERR_INSUFFICIENT_BUF) |
| 6540 | + call mpas_log_write('MPAS IO Error: Attempting to read a variable into a buffer of insufficient size.', MPAS_LOG_ERR) |
6501 | 6541 | case default |
6502 | 6542 | call mpas_log_write('MPAS IO Error: Unrecognized error code...', MPAS_LOG_ERR) |
6503 | 6543 | end select |
|
0 commit comments