IODA Bundle
odc_ls.f90
Go to the documentation of this file.
1 program odc_ls
2 
3  use, intrinsic :: iso_fortran_env
4  use odc
5  implicit none
6 
7  character(255) :: path
8  type(odc_reader) :: reader
9  type(odc_frame) :: frame
10  type(odc_decoder) :: decoder
11  integer(8) :: nrows
12  integer :: err, ncols
13 
14  if (command_argument_count() /= 1) then
15  call usage()
16  stop 1
17  end if
18 
19  call get_command_argument(1, path)
20  call check_call(odc_initialise_api(), "initialising api")
21 
22  call check_call(reader%open_path(trim(path)), "opening path")
23  call check_call(frame%initialise(reader), "initialising frame")
24 
25  err = frame%next()
26  do while (err == odc_success)
27 
28  call check_call(frame%column_count(ncols), "getting column count")
29  call write_header(frame, ncols)
30 
31  call check_call(decoder%initialise(), "initialising decoder")
32  call check_call(decoder%defaults_from_frame(frame), "setting decoder structure")
33  call check_call(decoder%decode(frame, nrows), "decoding data")
34  call write_data(decoder, frame, nrows, ncols)
35  call check_call(decoder%free(), "cleaning up decoder")
36 
37  err = frame%next()
38  end do
39 
40  if (err /= odc_iteration_complete) call check_call(err, "get next frame")
41 
42  call check_call(reader%close(), "closing reader")
43 
44 contains
45 
46  subroutine check_call(err, desc)
47  integer, intent(in) :: err
48  character(*), intent(in) :: desc
49 
50  if (err /= odc_success) then
51  write(error_unit, *) '**** An error occurred in ODC library'
52  write(error_unit, *) 'Description: ', desc
53  write(error_unit, *) 'Error: ', odc_error_string(err)
54  stop 1
55  end if
56  end subroutine
57 
58  subroutine usage()
59  write(error_unit,*) 'Usage:'
60  write(error_unit,*) ' odc-fortran-ls <odb2 file>'
61  end subroutine
62 
63  subroutine write_header(frame, ncols)
64  type(odc_frame), intent(in) :: frame
65  integer, intent(in) :: ncols
66  character(:), allocatable :: name_str
67  integer :: col
68 
69  do col = 1, ncols
70  call write_integer(output_unit, col)
71  call check_call(frame%column_attributes(col, name=name_str), "getting column name")
72  write(output_unit, '(3a)', advance='no') '. ', name_str, char(9)
73  end do
74  write(output_unit,*)
75  end subroutine
76 
77  subroutine write_data(decoder, frame, nrows, ncols)
78  type(odc_decoder), intent(inout) :: decoder
79  type(odc_frame), intent(in) :: frame
80  integer(8), intent(in) :: nrows
81  integer, intent(in) :: ncols
82  integer(8) :: row
83  real(8), pointer :: array_data(:,:)
84  integer :: ncols_decoder, ncols_frame, col, current_index
85  integer(8) :: missing_integer
86  real(8) :: missing_double
87  integer, dimension(ncols) :: types, sizes, indexes
88 
89  call check_call(decoder%data(array_data), "getting access to data")
90 
91  call check_call(decoder%column_count(ncols_decoder), "getting decoder column count")
92  call check_call(frame%column_count(ncols_frame), "getting frame column count")
93  if (ncols_decoder /= ncols_frame .or. ncols_decoder /= ncols) then
94  write(error_unit, *) 'Something went wrong in the decode target initialisation'
95  stop 1
96  end if
97 
98  current_index = 1
99  do col = 1, ncols
100  call check_call(frame%column_attributes(col, type=types(col)), "getting column type")
101  call check_call(decoder%column_data_array(col, element_size_doubles=sizes(col)), "getting element size")
102  indexes(col) = current_index
103  current_index = current_index + sizes(col)
104  end do
105 
106  call check_call(odc_missing_integer(missing_integer), "getting missing integer")
107  call check_call(odc_missing_double(missing_double), "getting missing double")
108 
109  do row = 1, nrows
110  do col = 1, ncols
111  select case(types(col))
112  case (odc_integer)
113  if (int(array_data(row, indexes(col))) == missing_integer) then
114  write(output_unit, '(a)', advance='no') '.'
115  else
116  call write_integer(output_unit, int(array_data(row, indexes(col))))
117  end if
118  case (odc_bitfield)
119  if (int(array_data(row, indexes(col))) == 0) then
120  write(output_unit, '(a)', advance='no') '.'
121  else
122  call write_integer(output_unit, int(array_data(row, indexes(col))))
123  end if
124  case (odc_real, odc_double)
125  if (array_data(row, indexes(col)) == missing_double) then
126  write(output_unit, '(a)', advance='no') '.'
127  else
128  call write_double(output_unit, array_data(row, indexes(col)))
129  end if
130  case (odc_string)
131  call write_string(output_unit, array_data(row, indexes(col):(indexes(col)+sizes(col)-1)))
132  case default
133  write(output_unit, '(a)', advance='no') '<unknown>'
134  end select
135  write(output_unit, '(a)', advance='no') char(9)
136  end do
137  write(output_unit, *)
138  end do
139  end subroutine
140 
141  subroutine write_integer(iunit, i)
142  integer, intent(in) :: iunit, i
143  character(32) :: val
144  write(val, *) i
145  write(iunit, '(a)', advance='no') trim(adjustl(val))
146  end subroutine
147 
148  subroutine write_double(iunit, r)
149  integer, intent(in) :: iunit
150  real(8), intent(in) :: r
151  character(32) :: val
152  write(val, *) r
153  write(iunit, '(a)', advance='no') trim(adjustl(val))
154  end subroutine
155 
156  subroutine write_string(iunit, double_string)
157  integer, intent(in) :: iunit
158  real(8), intent(in), dimension(:) :: double_string
159  character(8*size(double_string)) :: strtmp
160  if (all(transfer(double_string, 1_8, size(double_string)) == 0)) then
161  write(iunit, '(a)', advance='no') '.'
162  else
163  write(iunit, '(a)', advance='no') trim(adjustl(transfer(double_string, strtmp)))
164  end if
165  end subroutine
166 
167 end program
const char * odc_error_string(int err)
Definition: api/odc.cc:93
Definition: ColumnInfo.h:23
integer(c_int), parameter, public odc_real
Definition: odc.f90:9
integer, parameter, public odc_iteration_complete
Definition: odc.f90:17
integer(c_int), parameter, public odc_string
Definition: odc.f90:10
integer(c_int), parameter, public odc_double
Definition: odc.f90:12
integer(c_int), parameter, public odc_bitfield
Definition: odc.f90:11
integer(c_int), parameter, public odc_integer
Definition: odc.f90:8
integer, parameter, public odc_success
Definition: odc.f90:16
subroutine write_integer(iunit, i)
Definition: odc_ls.f90:142
subroutine write_data(decoder, frame, nrows, ncols)
Definition: odc_ls.f90:78
program odc_ls
Definition: odc_ls.f90:1
subroutine write_double(iunit, r)
Definition: odc_ls.f90:149
subroutine write_string(iunit, double_string)
Definition: odc_ls.f90:157
subroutine write_header(frame, ncols)
Definition: odc_ls.f90:64
subroutine check_call(err, desc)
Definition: odc_ls.f90:47