IODA Bundle
odc.f90
Go to the documentation of this file.
1 
2 module odc
3 
4  use, intrinsic :: iso_c_binding
5  implicit none
6 
7  integer(c_int), public, parameter :: odc_ignore = 0
8  integer(c_int), public, parameter :: odc_integer = 1
9  integer(c_int), public, parameter :: odc_real = 2
10  integer(c_int), public, parameter :: odc_string = 3
11  integer(c_int), public, parameter :: odc_bitfield = 4
12  integer(c_int), public, parameter :: odc_double = 5
13 
14  ! Error values
15 
16  integer, public, parameter :: odc_success = 0
17  integer, public, parameter :: odc_iteration_complete = 1
18  integer, public, parameter :: odc_error_general_exception = 2
19  integer, public, parameter :: odc_error_unknown_exception = 3
20 
21  private
22 
23  integer, parameter :: dp = selected_real_kind(15, 307)
24  integer, parameter :: double_size = 8 !c_sizeof(1.0_dp) !intel compiler...
25 
27  type(c_ptr) :: impl = c_null_ptr
28  contains
29  procedure :: open_path => reader_open_path
30  procedure :: close => reader_close
31  end type
32 
33  type odc_frame
34  type(c_ptr) :: impl = c_null_ptr
35  contains
36  procedure :: initialise => frame_initialise
37  procedure :: free => frame_free
38  procedure :: copy => frame_copy
39  procedure :: next => frame_next
40  procedure :: row_count => frame_row_count
41  procedure :: column_count => frame_column_count
42  procedure :: column_attributes => frame_column_attributes
43  procedure :: bitfield_attributes => frame_bitfield_attributes
44  end type
45 
47  type(c_ptr) :: impl = c_null_ptr
48  contains
49  procedure :: initialise => decoder_initialise
50  procedure :: free => decoder_free
51  procedure :: defaults_from_frame => decoder_defaults_from_frame
52  procedure :: set_row_count => decoder_set_row_count
53  procedure :: row_count => decoder_row_count
54  procedure :: set_data => decoder_set_data_array
55  procedure :: data => decoder_data_array
56  procedure :: add_column => decoder_add_column
57  procedure :: column_count => decoder_column_count
58  procedure :: column_set_data_size => decoder_column_set_data_size
59  procedure :: column_set_data_array => decoder_column_set_data_array
60  procedure :: column_data_array => decoder_column_data_array
61  procedure :: decode => decoder_decode
62  end type
63 
64 
66  type(c_ptr) :: impl = c_null_ptr
67  real, pointer, dimension(:,:) :: data_array => null()
68  logical :: column_major = .true.
69  contains
70  procedure :: initialise => encoder_initialise
71  procedure :: free => encoder_free
72  procedure :: set_row_count => encoder_set_row_count
73  procedure :: set_rows_per_frame => encoder_set_rows_per_frame
74  procedure :: set_data => encoder_set_data_array
75  procedure :: add_column => encoder_add_column
76  procedure :: column_set_data_size => encoder_column_set_data_size
77  procedure :: column_set_data_array => encoder_column_set_data_array
78  procedure :: column_add_bitfield => encoder_column_add_bitfield
79  procedure :: encode => encoder_encode
80  end type
81 
82  ! Type declarations
83 
84  public :: odc_reader
85  public :: odc_frame
86  public :: odc_encoder
87  public :: odc_decoder
88 
89  ! Configuration management functions
90 
91  public :: odc_version, odc_vcs_version
92  public :: odc_initialise_api
94  public :: odc_error_string
97  public :: odc_set_failure_handler
98 
99  ! Error handling definitions
100 
101  abstract interface
102  subroutine failure_handler_t(context, error)
103  use, intrinsic :: iso_c_binding
104  implicit none
105  integer, intent(in) :: error
106  integer(c_long), intent(in) :: context
107  end subroutine
108  end interface
109 
110  integer(c_long), save :: failure_handler_context
111  procedure(failure_handler_t), pointer, save :: failure_handler_fn
112 
113  ! For utility
114 
115  interface
116  pure function strlen(str) result(len) bind(c)
117  use, intrinsic :: iso_c_binding
118  implicit none
119  type(c_ptr), intent(in), value :: str
120  integer(c_int) :: len
121  end function
122  end interface
123 
124  ! Wrap the C api functions
125 
126  interface
127 
128  function c_odc_version(pstr) result(err) bind(c, name='odc_version')
129  use, intrinsic :: iso_c_binding
130  implicit none
131  type(c_ptr), intent(out) :: pstr
132  integer(c_int) :: err
133  end function
134 
135  function c_odc_vcs_version(pstr) result(err) bind(c, name='odc_vcs_version')
136  use, intrinsic :: iso_c_binding
137  implicit none
138  type(c_ptr), intent(out) :: pstr
139  integer(c_int) :: err
140  end function
141 
142  function odc_initialise_api() result(err) bind(c)
143  use, intrinsic :: iso_c_binding
144  implicit none
145  integer(c_int) :: err
146  end function
147 
148  function odc_integer_behaviour(integer_behaviour) result(err) bind(c)
149  use, intrinsic :: iso_c_binding
150  implicit none
151  integer(c_int), intent(in), value :: integer_behaviour
152  integer(c_int) :: err
153  end function
154 
155  function c_odc_set_failure_handler(handler, context) result(err) bind(c, name='odc_set_failure_handler')
156  use, intrinsic :: iso_c_binding
157  implicit none
158  type(c_funptr), intent(in), value :: handler
159  type(c_ptr), intent(in), value :: context
160  integer(c_int) :: err
161  end function
162 
163  function odc_halt_on_failure(halt) result(err) bind(c)
164  use, intrinsic :: iso_c_binding
165  implicit none
166  logical(c_bool), intent(in), value :: halt
167  integer(c_int) :: err
168  end function
169 
170  function c_odc_column_type_name(type, pstr) result(err) bind(c, name='odc_column_type_name')
171  use, intrinsic :: iso_c_binding
172  implicit none
173  integer(c_int), intent(in), value :: type
174  type(c_ptr), intent(out) :: pstr
175  integer(c_int) :: err
176  end function
177 
178  function odc_column_type_count(ntypes) result(err) bind(c)
179  use, intrinsic :: iso_c_binding
180  implicit none
181  integer(c_int), intent(out) :: ntypes
182  integer(c_int) :: err
183  end function
184 
185  function c_odc_error_string(err) result(error_string) bind(c, name='odc_error_string')
186  use, intrinsic :: iso_c_binding
187  implicit none
188  integer(c_int), intent(in), value :: err
189  type(c_ptr) :: error_string
190  end function
191 
192  function odc_missing_integer(missing_integer) result(err) bind(c)
193  use, intrinsic :: iso_c_binding
194  implicit none
195  integer(c_long), intent(out) :: missing_integer
196  integer(c_int) :: err
197  end function
198 
199  function odc_missing_double(missing_double) result(err) bind(c)
200  use, intrinsic :: iso_c_binding
201  implicit none
202  real(c_double), intent(out) :: missing_double
203  integer(c_int) :: err
204  end function
205 
206  function odc_set_missing_integer(missing_integer) result(err) bind(c)
207  use, intrinsic :: iso_c_binding
208  implicit none
209  integer(c_long), intent(in), value :: missing_integer
210  integer(c_int) :: err
211  end function
212 
213  function odc_set_missing_double(missing_double) result(err) bind(c)
214  use, intrinsic :: iso_c_binding
215  implicit none
216  real(c_double), intent(in), value :: missing_double
217  integer(c_int) :: err
218  end function
219 
220  ! READ object api
221 
222  function odc_open_path(reader, path) result(err) bind(c)
223  use, intrinsic :: iso_c_binding
224  implicit none
225  type(c_ptr), intent(in), value :: path
226  type(c_ptr), intent(out) :: reader
227  integer(c_int) :: err
228  end function
229 
230  function odc_close(reader) result(err) bind(c)
231  use, intrinsic :: iso_c_binding
232  implicit none
233  type(c_ptr), intent(in), value :: reader
234  integer(c_int) :: err
235  end function
236 
237  ! Frame functionality
238 
239  function odc_new_frame(frame, reader) result(err) bind(c)
240  use, intrinsic :: iso_c_binding
241  implicit none
242  type(c_ptr), intent(out) :: frame
243  type(c_ptr), intent(in), value :: reader
244  integer(c_int) :: err
245  end function
246 
247  function odc_free_frame(frame) result(err) bind(c)
248  use, intrinsic :: iso_c_binding
249  implicit none
250  type(c_ptr), intent(in), value :: frame
251  integer(c_int) :: err
252  end function
253 
254  function odc_next_frame(frame) result(err) bind(c)
255  use, intrinsic :: iso_c_binding
256  implicit none
257  type(c_ptr), intent(in), value :: frame
258  integer(c_int) :: err
259  end function
260 
261  function odc_next_frame_aggregated(frame, maximum_rows) result(err) bind(c)
262  use, intrinsic :: iso_c_binding
263  implicit none
264  type(c_ptr), intent(in), value :: frame
265  integer(c_long), intent(in), value :: maximum_rows
266  integer(c_int) :: err
267  end function
268 
269  function odc_copy_frame(source_frame, copy) result(err) bind(c)
270  use, intrinsic :: iso_c_binding
271  implicit none
272  type(c_ptr), intent(in), value :: source_frame
273  type(c_ptr), intent(out) :: copy
274  integer(c_int) :: err
275  end function
276 
277  function odc_frame_row_count(frame, count) result(err) bind(c)
278  use, intrinsic :: iso_c_binding
279  implicit none
280  type(c_ptr), intent(in), value :: frame
281  integer(c_long), intent(out) :: count
282  integer(c_int) :: err
283  end function
284 
285  function odc_frame_column_count(frame, count) result(err) bind(c)
286  use, intrinsic :: iso_c_binding
287  implicit none
288  type(c_ptr), intent(in), value :: frame
289  integer(c_int), intent(out) :: count
290  integer(c_int) :: err
291  end function
292 
293  function odc_frame_column_attributes(frame, col, name, type, element_size, bitfield_count) result(err) bind(c)
294  ! n.b. 0-indexed column (C API)
295  use, intrinsic :: iso_c_binding
296  implicit none
297  type(c_ptr), intent(in), value :: frame
298  integer(c_int), intent(in), value :: col
299  type(c_ptr), intent(out) :: name
300  integer(c_int), intent(out) :: type
301  integer(c_int), intent(out) :: element_size
302  integer(c_int), intent(out) :: bitfield_count
303  integer(c_int) :: err
304  end function
305 
306  function odc_frame_bitfield_attributes(frame, col, field, name, offset, size) result(err) bind(c)
307  ! n.b. 0-indexed column (C API)
308  use, intrinsic :: iso_c_binding
309  implicit none
310  type(c_ptr), intent(in), value :: frame
311  integer(c_int), intent(in), value :: col
312  integer(c_int), intent(in), value :: field
313  type(c_ptr), intent(out) :: name
314  integer(c_int), intent(out) :: offset
315  integer(c_int), intent(out) :: size
316  integer(c_int) :: err
317  end function
318 
319  ! Work with decoders
320 
321  function odc_new_decoder(decoder) result(err) bind(c)
322  use, intrinsic :: iso_c_binding
323  implicit none
324  type(c_ptr), intent(out) :: decoder
325  integer(c_int) :: err
326  end function
327 
328  function odc_free_decoder(decoder) result(err) bind(c)
329  use, intrinsic :: iso_c_binding
330  implicit none
331  type(c_ptr), intent(in), value :: decoder
332  integer(c_int) :: err
333  end function
334 
335  function odc_decoder_defaults_from_frame(decoder, frame) result(err) bind(c)
336  use, intrinsic :: iso_c_binding
337  implicit none
338  type(c_ptr), intent(in), value :: decoder
339  type(c_ptr), intent(in), value :: frame
340  integer(c_int) :: err
341  end function
342 
343  function odc_decoder_set_column_major(decoder, columnMajor) result(err) bind(c)
344  use, intrinsic :: iso_c_binding
345  implicit none
346  type(c_ptr), intent(in), value :: decoder
347  logical(c_bool), intent(in), value :: columnmajor
348  integer(c_int) :: err
349  end function
350 
351  function odc_decoder_set_row_count(decoder, row_count) result(err) bind(c)
352  use, intrinsic :: iso_c_binding
353  implicit none
354  type(c_ptr), intent(in), value :: decoder
355  integer(c_long), intent(in), value :: row_count
356  integer(c_int) :: err
357  end function
358 
359  function odc_decoder_row_count(decoder, row_count) result(err) bind(c)
360  use, intrinsic :: iso_c_binding
361  implicit none
362  type(c_ptr), intent(in), value :: decoder
363  integer(c_long), intent(out) :: row_count
364  integer(c_int) :: err
365  end function
366 
367  function odc_decoder_set_data_array(decoder, data, width, height, columnMajor) result(err) bind(c)
368  use, intrinsic :: iso_c_binding
369  implicit none
370  type(c_ptr), intent(in), value :: decoder
371  type(c_ptr), intent(in), value :: data
372  integer(c_long), intent(in), value :: width
373  integer(c_long), intent(in), value :: height
374  logical(c_bool), intent(in), value :: columnmajor
375  integer(c_int) :: err
376  end function
377 
378  function odc_decoder_data_array(decoder, data, width, height, columnMajor) result(err) bind(c)
379  use, intrinsic :: iso_c_binding
380  implicit none
381  type(c_ptr), intent(in), value :: decoder
382  type(c_ptr), intent(out) :: data
383  integer(c_long), intent(out) :: width
384  integer(c_long), intent(out) :: height
385  logical(c_bool), intent(out) :: columnmajor
386  integer(c_int) :: err
387  end function
388 
389  function odc_decoder_add_column(decoder, name) result(err) bind(c)
390  use, intrinsic :: iso_c_binding
391  implicit none
392  type(c_ptr), intent(in), value :: decoder
393  type(c_ptr), intent(in), value :: name
394  integer(c_int) :: err
395  end function
396 
397  function odc_decoder_column_count(decoder, count) result(err) bind(c)
398  use, intrinsic :: iso_c_binding
399  implicit none
400  type(c_ptr), intent(in), value :: decoder
401  integer(c_int), intent(out) :: count
402  integer(c_int) :: err
403  end function
404 
405  function odc_decoder_column_set_data_size(decoder, col, element_size) result(err) bind(c)
406  ! n.b. 0-indexed column (C API)
407  use, intrinsic :: iso_c_binding
408  implicit none
409  type(c_ptr), intent(in), value :: decoder
410  integer(c_int), intent(in), value :: col
411  integer(c_int), intent(in), value :: element_size
412  integer(c_int) :: err
413  end function
414 
415  function odc_decoder_column_set_data_array(decoder, col, element_size, stride, data) result(err) bind(c)
416  ! n.b. 0-indexed column (C API)
417  use, intrinsic :: iso_c_binding
418  implicit none
419  type(c_ptr), intent(in), value :: decoder
420  integer(c_int), intent(in), value :: col
421  integer(c_int), intent(in), value :: element_size
422  integer(c_int), intent(in), value :: stride
423  type(c_ptr), intent(in), value :: data
424  integer(c_int) :: err
425  end function
426 
427  function odc_decoder_column_data_array(decoder, col, element_size, stride, data) result(err) bind(c)
428  ! n.b. 0-indexed column (C API)
429  use, intrinsic :: iso_c_binding
430  implicit none
431  type(c_ptr), intent(in), value :: decoder
432  integer(c_int), intent(in), value :: col
433  integer(c_int), intent(out) :: element_size
434  integer(c_int), intent(out) :: stride
435  type(c_ptr), intent(out) :: data
436  integer(c_int) :: err
437  end function
438 
439  ! Do actual decoding
440 
441  function odc_decode(decoder, frame, rows_decoded) result(err) bind(c)
442  use, intrinsic :: iso_c_binding
443  implicit none
444  type(c_ptr), intent(in), value :: decoder
445  type(c_ptr), intent(in), value :: frame
446  integer(c_long), intent(out) :: rows_decoded
447  integer(c_int) :: err
448  end function
449 
450  function odc_decode_threaded(decoder, frame, rows_decoded, nthreads) result(err) bind(c)
451  use, intrinsic :: iso_c_binding
452  implicit none
453  type(c_ptr), intent(in), value :: decoder
454  type(c_ptr), intent(in), value :: frame
455  integer(c_long), intent(out) :: rows_decoded
456  integer(c_int), intent(in), value :: nthreads
457  integer(c_int) :: err
458  end function
459 
460  ! Work with encoders
461 
462  function odc_new_encoder(encoder) result(err) bind(c)
463  use, intrinsic :: iso_c_binding
464  implicit none
465  type(c_ptr), intent(out) :: encoder
466  integer(c_int) :: err
467  end function
468 
469  function odc_free_encoder(encoder) result(err) bind(c)
470  use, intrinsic :: iso_c_binding
471  implicit none
472  type(c_ptr), intent(in), value :: encoder
473  integer(c_int) :: err
474  end function
475 
476  function odc_encoder_set_row_count(encoder, row_count) result(err) bind(c)
477  use, intrinsic :: iso_c_binding
478  implicit none
479  type(c_ptr), intent(in), value :: encoder
480  integer(c_long), intent(in), value :: row_count
481  integer(c_int) :: err
482  end function
483 
484  function odc_encoder_set_rows_per_frame(encoder, rows_per_frame) result(err) bind(c)
485  use, intrinsic :: iso_c_binding
486  implicit none
487  type(c_ptr), intent(in), value :: encoder
488  integer(c_long), intent(in), value :: rows_per_frame
489  integer(c_int) :: err
490  end function
491 
492  function odc_encoder_set_data_array(encoder, data, width, height, columnMajorWidth) result(err) bind(c)
493  use, intrinsic :: iso_c_binding
494  implicit none
495  type(c_ptr), intent(in), value :: encoder
496  type(c_ptr), intent(in), value :: data
497  integer(c_long), intent(in), value :: width
498  integer(c_long), intent(in), value :: height
499  integer(c_int), intent(in), value :: columnmajorwidth
500  integer(c_int) :: err
501  end function
502 
503  function odc_encoder_add_column(encoder, name, type) result(err) bind(c)
504  use, intrinsic :: iso_c_binding
505  implicit none
506  type(c_ptr), intent(in), value :: encoder
507  type(c_ptr), intent(in), value :: name
508  integer(c_int), intent(in), value :: type
509  integer(c_int) :: err
510  end function
511 
512  function odc_encoder_column_set_data_size(encoder, col, element_size) result(err) bind(c)
513  ! n.b. 0-indexed column (C API)
514  use, intrinsic :: iso_c_binding
515  implicit none
516  type(c_ptr), intent(in), value :: encoder
517  integer(c_int), intent(in), value :: col
518  integer(c_int), intent(in), value :: element_size
519  integer(c_int) :: err
520  end function
521 
522  function odc_encoder_column_set_data_array(encoder, col, element_size, stride, data) result(err) bind(c)
523  ! n.b. 0-indexed column (C API)
524  use, intrinsic :: iso_c_binding
525  implicit none
526  type(c_ptr), intent(in), value :: encoder
527  integer(c_int), intent(in), value :: col
528  integer(c_int), intent(in), value :: element_size
529  integer(c_int), intent(in), value :: stride
530  type(c_ptr), intent(in), value :: data
531  integer(c_int) :: err
532  end function
533 
534  function odc_encoder_column_add_bitfield(encoder, col, name, nbits) result(err) bind(c)
535  ! n.b. 0-indexed column (C API)
536  use, intrinsic :: iso_c_binding
537  implicit none
538  type(c_ptr), intent(in), value :: encoder
539  integer(c_int), intent(in), value :: col
540  type(c_ptr), intent(in), value :: name
541  integer(c_int), intent(in), value :: nbits
542  integer(c_int) :: err
543  end function
544 
545  function odc_encode_to_stream(encoder, handle, stream_fn, bytes_encoded) result(err) bind(c)
546  use, intrinsic :: iso_c_binding
547  implicit none
548  type(c_ptr), intent(in), value :: encoder
549  type(c_ptr), intent(in), value :: handle
550  type(c_funptr), intent(in), value :: stream_fn
551  integer(c_long), intent(out) :: bytes_encoded
552  integer(c_int) :: err
553  end function
554  end interface
555 
556 contains
557 
558  !function transfer_cstr(cstr, l) result(fstr)
559  ! type(c_ptr), intent(in) :: cstr
560  ! integer, intent(in) :: l
561  ! character(l) :: fstr
562  ! character(c_char), pointer :: tmp(:)
563  ! call c_f_pointer(cstr, tmp, [l])
564  ! fstr = transfer(tmp(1:l), fstr)
565  !end function
566 
567  function fortranise_cstr(cstr) result(fstr)
568  type(c_ptr), intent(in) :: cstr
569  character(:), allocatable, target :: fstr
570  character(c_char), pointer :: tmp(:)
571  integer :: length
572 
573  length = strlen(cstr)
574  allocate(character(length) :: fstr)
575  call c_f_pointer(cstr, tmp, [length])
576  fstr = transfer(tmp(1:length), fstr)
577  end function
578 
579  subroutine failure_handler_wrapper(unused_context, error)
580  type(c_ptr), intent(in), value :: unused_context
581  integer(c_long), intent(in), value :: error
583  end subroutine
584 
585  function odc_set_failure_handler(handler, context) result(err)
586  procedure(failure_handler_t), pointer :: handler
587  integer(c_long) :: context
588  integer :: err
589  failure_handler_fn => handler
590  failure_handler_context = context
591  err = c_odc_set_failure_handler(c_funloc(failure_handler_wrapper), c_null_ptr)
592  end function
593 
594  function odc_version(version_str) result(err)
595  character(:), allocatable, intent(out) :: version_str
596  type(c_ptr) :: tmp_str
597  integer :: err
598  err = c_odc_version(tmp_str)
599  if (err == odc_success) version_str = fortranise_cstr(tmp_str)
600  end function
601 
602  function odc_vcs_version(git_sha1) result(err)
603  character(:), allocatable, intent(out) :: git_sha1
604  type(c_ptr) :: tmp_str
605  integer :: err
606  err = c_odc_vcs_version(tmp_str)
607  if (err == odc_success) git_sha1 = fortranise_cstr(tmp_str)
608  end function
609 
610  function odc_column_type_name(type, type_name) result(err)
611  integer(c_int), intent(in) :: type
612  character(:), allocatable, intent(out) :: type_name
613  type(c_ptr) :: tmp_str
614  integer :: err
615  err = c_odc_column_type_name(type, tmp_str)
616  if (err == odc_success) type_name = fortranise_cstr(tmp_str)
617  end function
618 
619  function odc_error_string(err) result(error_string)
620  integer, intent(in) :: err
621  character(:), allocatable, target :: error_string
622  error_string = fortranise_cstr(c_odc_error_string(err))
623  end function
624 
625  ! Methods for reader objects
626 
627  function reader_open_path(reader, path) result(err)
628  class(odc_reader), intent(inout) :: reader
629  character(*), intent(in) :: path
630  integer :: err
631  character(:), allocatable, target :: nullified_path
632  nullified_path = trim(path) // c_null_char
633  err = odc_open_path(reader%impl, c_loc(nullified_path))
634  end function
635 
636  function reader_close(reader) result(err)
637  class(odc_reader), intent(inout) :: reader
638  integer :: err
639  err = odc_close(reader%impl)
640  reader%impl = c_null_ptr
641  end function
642 
643  ! Methods for frame object
644 
645  function frame_initialise(frame, reader) result(err)
646  class(odc_frame), intent(inout) :: frame
647  type(odc_reader), intent(inout) :: reader
648  integer :: err
649  err = odc_new_frame(frame%impl, reader%impl)
650  end function
651 
652  function frame_free(frame) result(err)
653  class(odc_frame), intent(inout) :: frame
654  integer :: err
655  err = odc_free_frame(frame%impl)
656  end function
657 
658  function frame_copy(frame, new_frame) result(err)
659  class(odc_frame), intent(inout) :: frame
660  class(odc_frame), intent(inout) :: new_frame
661  integer :: err
662  err = odc_copy_frame(frame%impl, new_frame%impl)
663  end function
664 
665  function frame_next(frame, aggregated, maximum_rows) result(err)
666  class(odc_frame), intent(inout) :: frame
667  logical, intent(in), optional :: aggregated
668  integer(c_long), intent(in), optional :: maximum_rows
669  integer :: err
670 
671  integer(c_long) :: l_maximum_rows = -1
672  logical :: l_aggregated = .false.
673 
674  if (present(aggregated)) l_aggregated = aggregated
675  if (present(maximum_rows)) then
676  l_maximum_rows = maximum_rows
677  if (.not. present(aggregated)) l_aggregated = .true.
678  end if
679 
680  if (l_aggregated) then
681  err = odc_next_frame_aggregated(frame%impl, l_maximum_rows)
682  else
683  err = odc_next_frame(frame%impl)
684  end if
685  end function
686 
687  function frame_row_count(frame, nrows) result(err)
688  class(odc_frame), intent(in) :: frame
689  integer(c_long), intent(out) :: nrows
690  integer :: err
691  err = odc_frame_row_count(frame%impl, nrows)
692  end function
693 
694  function frame_column_count(frame, ncols) result(err)
695  class(odc_frame), intent(in) :: frame
696  integer(c_int), intent(out) :: ncols
697  integer :: err
698  err = odc_frame_column_count(frame%impl, ncols)
699  end function
700 
701  function frame_column_attributes(frame, col, name, type, element_size, element_size_doubles, bitfield_count) result(err)
702  ! n.b. 1-indexed column (Fortran API)
703  class(odc_frame), intent(in) :: frame
704  integer, intent(in) :: col
705  integer :: err
706 
707  character(:), allocatable, intent(out), optional :: name
708  integer, intent(out), optional :: type
709  integer, intent(out), optional :: element_size
710  integer, intent(out), optional :: element_size_doubles
711  integer, intent(out), optional :: bitfield_count
712 
713  type(c_ptr) :: name_tmp
714  integer(c_int) :: type_tmp
715  integer(c_int) :: element_size_tmp
716  integer(c_int) :: bitfield_count_tmp
717 
718  err = odc_frame_column_attributes(frame%impl, col-1, name_tmp, type_tmp,&
719  element_size_tmp, bitfield_count_tmp)
720 
721  if (err == odc_success) then
722  if (present(name)) name = fortranise_cstr(name_tmp)
723  if (present(type)) type = type_tmp
724  if (present(element_size)) element_size = element_size_tmp
725  if (present(element_size_doubles)) element_size_doubles = element_size_tmp / double_size
726  if (present(bitfield_count)) bitfield_count = bitfield_count_tmp
727  end if
728 
729  end function
730 
731  function frame_bitfield_attributes(frame, col, field, name, offset, size) result(err)
732  ! n.b. 1-indexed column (Fortran API)
733  class(odc_frame), intent(in) :: frame
734  integer, intent(in) :: col
735  integer, intent(in) :: field
736  integer :: err
737 
738  character(:), allocatable, intent(out), optional :: name
739  integer, intent(out), optional :: offset
740  integer, intent(out), optional :: size
741 
742  type(c_ptr) :: name_tmp
743  integer(c_int) :: offset_tmp
744  integer(c_int) :: size_tmp
745 
746  err = odc_frame_bitfield_attributes(frame%impl, col-1, field-1, name_tmp, offset_tmp, size_tmp)
747 
748  if (err == odc_success) then
749  if (present(name)) name = fortranise_cstr(name_tmp)
750  if (present(offset)) offset = offset_tmp
751  if (present(size)) size = size_tmp
752  end if
753 
754  end function
755 
756  ! Methods for decoder object
757 
758  function decoder_initialise(decoder, column_major) result(err)
759  class(odc_decoder), intent(inout) :: decoder
760  logical, intent(in), optional :: column_major
761  integer :: err
762  logical(c_bool) :: l_column_major = .true.
763  if (present(column_major)) l_column_major = column_major
764  err = odc_new_decoder(decoder%impl)
765  if (err == odc_success) then
766  err = odc_decoder_set_column_major(decoder%impl, l_column_major)
767  end if
768  end function
769 
770  function decoder_free(decoder) result(err)
771  class(odc_decoder), intent(inout) :: decoder
772  integer :: err
773  err = odc_free_decoder(decoder%impl)
774  end function
775 
776  function decoder_defaults_from_frame(decoder, frame) result(err)
777  class(odc_decoder), intent(inout) :: decoder
778  type(odc_frame), intent(in) :: frame
779  integer :: err
780  err = odc_decoder_defaults_from_frame(decoder%impl, frame%impl)
781  end function
782 
783  function decoder_set_row_count(decoder, count) result(err)
784  class(odc_decoder), intent(inout) :: decoder
785  integer(c_long), intent(in) :: count
786  integer :: err
787  err = odc_decoder_set_row_count(decoder%impl, count)
788  end function
789 
790  function decoder_row_count(decoder, count) result(err)
791  class(odc_decoder), intent(in) :: decoder
792  integer(c_long), intent(out) :: count
793  integer :: err
794  err = odc_decoder_row_count(decoder%impl, count)
795  end function
796 
797  function decoder_set_data_array(decoder, data, column_major) result(err)
798  class(odc_decoder), intent(inout) :: decoder
799  real(dp), intent(inout), target :: data(:,:)
800  logical, intent(in), optional :: column_major
801  integer(c_long) :: width, height
802  logical(c_bool) :: l_column_major = .true.
803  integer :: err
804  if (present(column_major)) l_column_major = column_major
805  if (l_column_major) then
806  width = size(data, 2) * double_size
807  height = size(data, 1)
808  else
809  width = size(data, 1) * double_size
810  height = size(data, 2)
811  end if
812  err = odc_decoder_set_data_array(decoder%impl, c_loc(data), width, height, l_column_major)
813  end function
814 
815  function decoder_data_array(decoder, data, column_major) result(err)
816  class(odc_decoder), intent(in) :: decoder
817  real(dp), intent(inout), pointer, optional :: data(:,:)
818  logical, intent(out), optional :: column_major
819  integer :: err
820 
821  type(c_ptr) :: cdata
822  integer(c_long) :: width, height
823  logical(c_bool) :: cmajor
824 
825  err = odc_decoder_data_array(decoder%impl, cdata, width, height, cmajor)
826 
827  if (err == odc_success) then
828  if (present(data)) then
829  if (cmajor) then
830  call c_f_pointer(cdata, data, [height, width / double_size])
831  else
832  call c_f_pointer(cdata, data, [width / double_size, height])
833  end if
834  end if
835  if (present(column_major)) column_major = cmajor
836  end if
837 
838  end function
839 
840  function decoder_add_column(decoder, name) result(err)
841  class(odc_decoder), intent(inout) :: decoder
842  character(*), intent(in) :: name
843  character(:), allocatable, target :: nullified_name
844  integer :: err
845 
846  nullified_name = trim(name) // c_null_char
847  err = odc_decoder_add_column(decoder%impl, c_loc(nullified_name))
848  end function
849 
850  function decoder_column_count(decoder, count) result(err)
851  class(odc_decoder), intent(in) :: decoder
852  integer, intent(out) :: count
853  integer(c_int) :: count_tmp
854  integer :: err
855  err = odc_decoder_column_count(decoder%impl, count_tmp)
856  count = count_tmp
857  end function
858 
859  function decoder_column_set_data_size(decoder, col, element_size) result(err)
860  ! n.b. 1-indexed column (Fortran API)
861  class(odc_decoder), intent(inout) :: decoder
862  integer, intent(in) :: col
863  integer(c_int), intent(in) :: element_size
864  integer :: err
865 
866  err = odc_decoder_column_set_data_size(decoder%impl, col-1, element_size)
867  end function
868 
869  function decoder_column_set_data_array(decoder, col, element_size, stride, data) result(err)
870  ! n.b. 1-indexed column (Fortran API)
871  class(odc_decoder), intent(inout) :: decoder
872  integer, intent(in) :: col
873  integer, intent(in), optional :: element_size
874  integer, intent(in), optional :: stride
875  type(c_ptr), intent(in), optional :: data
876  integer :: err
877 
878  integer(c_int) :: l_element_size = 0
879  integer(c_int) :: l_stride = 0
880  type(c_ptr) :: l_data = c_null_ptr
881  if (present(element_size)) l_element_size = element_size
882  if (present(stride)) l_stride = stride
883  if (present(data)) l_data = data
884 
885  err = odc_decoder_column_set_data_array(decoder%impl, col-1, l_element_size, l_stride, l_data)
886  end function
887 
888  function decoder_column_data_array(decoder, col, element_size, element_size_doubles, stride, data) result(err)
889  ! n.b. 1-indexed column (Fortran API)
890  class(odc_decoder), intent(in) :: decoder
891  integer, intent(in) :: col
892  integer, intent(out), optional :: element_size
893  integer, intent(out), optional :: element_size_doubles
894  integer, intent(out), optional :: stride
895  type(c_ptr), intent(out), optional :: data
896  integer :: err
897 
898  integer(c_int) :: l_element_size
899  integer(c_int) :: l_stride
900  type(c_ptr) :: l_data
901 
902  err = odc_decoder_column_data_array(decoder%impl, col-1, l_element_size, l_stride, l_data)
903 
904  if (err == odc_success) then
905  if (present(element_size)) element_size = l_element_size
906  if (present(element_size_doubles)) element_size_doubles = l_element_size / double_size
907  if (present(stride)) stride = l_stride
908  if (present(data)) data = l_data
909  end if
910  end function
911 
912  function decoder_decode(decoder, frame, rows_decoded, nthreads) result(err)
913  class(odc_decoder), intent(inout) :: decoder
914  class(odc_frame), intent(inout) :: frame
915  integer(c_long), intent(out) :: rows_decoded
916  integer, intent(in), optional :: nthreads
917  integer :: err
918 
919  if (present(nthreads)) then
920  err = odc_decode_threaded(decoder%impl, frame%impl, rows_decoded, nthreads)
921  else
922  err = odc_decode(decoder%impl, frame%impl, rows_decoded)
923  end if
924  end function
925 
926  ! Methods for the encoder
927 
928  function encoder_initialise(encoder) result(err)
929  class(odc_encoder), intent(inout) :: encoder
930  integer :: err
931  err = odc_new_encoder(encoder%impl)
932  end function
933 
934  function encoder_free(encoder) result(err)
935  class(odc_encoder), intent(inout) :: encoder
936  integer :: err
937  err = odc_free_encoder(encoder%impl)
938  end function
939 
940  function encoder_set_row_count(encoder, row_count) result(err)
941  class(odc_encoder), intent(inout) :: encoder
942  integer(c_long), intent(in) :: row_count
943  integer :: err
944  err = odc_encoder_set_row_count(encoder%impl, row_count)
945  end function
946 
947  function encoder_set_rows_per_frame(encoder, rows_per_frame) result(err)
948  class(odc_encoder), intent(inout) :: encoder
949  integer(c_long), intent(in) :: rows_per_frame
950  integer :: err
951  err = odc_encoder_set_rows_per_frame(encoder%impl, rows_per_frame)
952  end function
953 
954  function encoder_set_data_array(encoder, data, column_major) result(err)
955  class(odc_encoder), intent(inout) :: encoder
956  real(dp), intent(in), target :: data(:,:)
957  logical, intent(in), optional :: column_major
958  integer(c_long) :: width, height
959  integer(c_int) :: columnmajorwidth
960  integer :: err
961  logical(c_bool) :: l_column_major = .true.
962 
963  if (present(column_major)) l_column_major = column_major
964  if (l_column_major) then
965  width = size(data, 2) * double_size
966  height = size(data, 1)
967  columnmajorwidth = 8
968  else
969  width = size(data, 1) * double_size
970  height = size(data, 2)
971  columnmajorwidth = 0
972  end if
973  err = odc_encoder_set_data_array(encoder%impl, c_loc(data), width, height, columnmajorwidth)
974  end function
975 
976  function encoder_add_column(encoder, name, type) result(err)
977  class(odc_encoder), intent(inout) :: encoder
978  character(*), intent(in) :: name
979  integer, intent(in) :: type
980  integer :: err
981  character(:), allocatable, target :: nullified_name
982  nullified_name = trim(name) // c_null_char
983  err = odc_encoder_add_column(encoder%impl, c_loc(nullified_name), type)
984  end function
985 
986  function encoder_column_set_data_size(encoder, col, element_size, element_size_doubles) result(err)
987  ! n.b. 1-indexed column (Fortran API)
988  class(odc_encoder), intent(inout) :: encoder
989  integer, intent(in) :: col
990  integer, intent(in), optional :: element_size
991  integer, intent(in), optional :: element_size_doubles
992  integer :: err
993 
994 
995  integer(c_int) :: l_element_size = 0
996  if (present(element_size)) l_element_size = element_size
997  if (present(element_size_doubles)) l_element_size = element_size_doubles * double_size
998 
999  err = odc_encoder_column_set_data_size(encoder%impl, col-1, l_element_size)
1000  end function
1001 
1002  function encoder_column_set_data_array(encoder, col, element_size, element_size_doubles, stride, data) result(err)
1003  ! n.b. 1-indexed column (Fortran API)
1004  class(odc_encoder), intent(inout) :: encoder
1005  integer, intent(in) :: col
1006  integer, intent(in), optional :: element_size
1007  integer, intent(in), optional :: element_size_doubles
1008  integer, intent(in), optional :: stride
1009  type(c_ptr), intent(in), optional :: data
1010  integer :: err
1011 
1012  integer(c_int) :: l_element_size = 0
1013  integer(c_int) :: l_stride = 0
1014  type(c_ptr) :: l_data = c_null_ptr
1015  if (present(element_size)) l_element_size = element_size
1016  if (present(element_size_doubles)) l_element_size = element_size_doubles * double_size
1017  if (present(stride)) l_stride = stride
1018  if (present(data)) l_data = data
1019 
1020  err = odc_encoder_column_set_data_array(encoder%impl, col-1, l_element_size, l_stride, l_data)
1021  end function
1022 
1023  function encoder_column_add_bitfield(encoder, col, name, nbits) result(err)
1024  ! n.b. 1-indexed column (Fortran API)
1025  class(odc_encoder), intent(inout) :: encoder
1026  integer, intent(in) :: col
1027  character(*), intent(in) :: name
1028  integer, intent(in) :: nbits
1029  integer :: err
1030  character(:), allocatable, target :: nullified_name
1031  nullified_name = trim(name) // c_null_char
1032  err = odc_encoder_column_add_bitfield(encoder%impl, col-1, c_loc(nullified_name), nbits)
1033  end function
1034 
1035  ! Helper function for streamage
1036 
1037  function write_fn(context, buffer, length) result(written) bind(c)
1038  type(c_ptr), intent(in), value :: context
1039  type(c_ptr), intent(in), value :: buffer
1040  integer(c_long), intent(in), value :: length
1041  integer(c_long) :: written
1042  integer, pointer :: fortran_unit
1043  character(c_char), pointer :: fortran_buffer(:)
1044 
1045  call c_f_pointer(context, fortran_unit)
1046  call c_f_pointer(buffer, fortran_buffer, [length])
1047  write(fortran_unit) fortran_buffer
1048  written = length
1049  end function
1050 
1051  function encoder_encode(encoder, outunit, bytes_written) result(err)
1052  class(odc_encoder), intent(inout) :: encoder
1053  integer, intent(in), target :: outunit
1054  integer(c_long), intent(out) :: bytes_written
1055  integer :: err
1056 
1057  err = odc_encode_to_stream(encoder%impl, c_loc(outunit), c_funloc(write_fn), bytes_written)
1058 
1059  end function
1060 
1061 end module
static void count(void *counter, const double *data, size_t n)
Definition: UnitTests.cc:531
int odc_vcs_version(const char **sha1)
Definition: api/odc.cc:275
int odc_column_type_name(int type, const char **type_name)
Definition: api/odc.cc:169
const char * odc_error_string(int err)
Definition: api/odc.cc:93
int odc_set_failure_handler(odc_failure_handler_t handler, void *context)
Definition: api/odc.cc:235
int odc_version(const char **version)
Definition: api/odc.cc:269
long(* write_fn)(void *handle, const void *buffer, long length)
Definition: encode.cc:607
Definition: ColumnInfo.h:23
integer function decoder_set_data_array(decoder, data, column_major)
Definition: odc.f90:798
integer function decoder_free(decoder)
Definition: odc.f90:771
integer function decoder_decode(decoder, frame, rows_decoded, nthreads)
Definition: odc.f90:913
integer(c_long), save failure_handler_context
Definition: odc.f90:110
integer(c_int), parameter, public odc_real
Definition: odc.f90:9
integer, parameter, public odc_error_unknown_exception
Definition: odc.f90:19
integer function encoder_set_data_array(encoder, data, column_major)
Definition: odc.f90:955
integer function frame_column_count(frame, ncols)
Definition: odc.f90:695
integer function encoder_initialise(encoder)
Definition: odc.f90:929
integer function frame_bitfield_attributes(frame, col, field, name, offset, size)
Definition: odc.f90:732
integer function frame_initialise(frame, reader)
Definition: odc.f90:646
integer function encoder_encode(encoder, outunit, bytes_written)
Definition: odc.f90:1052
integer function decoder_column_count(decoder, count)
Definition: odc.f90:851
integer, parameter dp
Definition: odc.f90:23
integer, parameter, public odc_iteration_complete
Definition: odc.f90:17
integer function reader_open_path(reader, path)
Definition: odc.f90:628
integer(c_int), parameter, public odc_string
Definition: odc.f90:10
integer(c_int), parameter, public odc_double
Definition: odc.f90:12
integer, parameter, public odc_error_general_exception
Definition: odc.f90:18
integer(c_int), parameter, public odc_bitfield
Definition: odc.f90:11
integer(c_int), parameter, public odc_ignore
Definition: odc.f90:7
integer function decoder_row_count(decoder, count)
Definition: odc.f90:791
integer function frame_copy(frame, new_frame)
Definition: odc.f90:659
integer function decoder_data_array(decoder, data, column_major)
Definition: odc.f90:816
integer function decoder_set_row_count(decoder, count)
Definition: odc.f90:784
integer function frame_row_count(frame, nrows)
Definition: odc.f90:688
subroutine failure_handler_wrapper(unused_context, error)
Definition: odc.f90:580
integer function decoder_defaults_from_frame(decoder, frame)
Definition: odc.f90:777
integer function frame_next(frame, aggregated, maximum_rows)
Definition: odc.f90:666
integer function decoder_column_set_data_array(decoder, col, element_size, stride, data)
Definition: odc.f90:870
integer, parameter double_size
Definition: odc.f90:24
integer(c_int), parameter, public odc_integer
Definition: odc.f90:8
integer function reader_close(reader)
Definition: odc.f90:637
integer function encoder_column_set_data_array(encoder, col, element_size, element_size_doubles, stride, data)
Definition: odc.f90:1003
integer function encoder_column_set_data_size(encoder, col, element_size, element_size_doubles)
Definition: odc.f90:987
integer function encoder_set_row_count(encoder, row_count)
Definition: odc.f90:941
integer, parameter, public odc_success
Definition: odc.f90:16
integer function frame_free(frame)
Definition: odc.f90:653
integer function decoder_column_data_array(decoder, col, element_size, element_size_doubles, stride, data)
Definition: odc.f90:889
procedure(failure_handler_t), pointer, save failure_handler_fn
Definition: odc.f90:111
integer function encoder_free(encoder)
Definition: odc.f90:935
integer function encoder_add_column(encoder, name, type)
Definition: odc.f90:977
character(:) function, allocatable, target fortranise_cstr(cstr)
Definition: odc.f90:568
integer function frame_column_attributes(frame, col, name, type, element_size, element_size_doubles, bitfield_count)
Definition: odc.f90:702
integer function encoder_column_add_bitfield(encoder, col, name, nbits)
Definition: odc.f90:1024
integer function decoder_column_set_data_size(decoder, col, element_size)
Definition: odc.f90:860
integer function encoder_set_rows_per_frame(encoder, rows_per_frame)
Definition: odc.f90:948
integer function decoder_add_column(decoder, name)
Definition: odc.f90:841
integer function decoder_initialise(decoder, column_major)
Definition: odc.f90:759