File: odc_header.f90

package info (click to toggle)
odc 1.6.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,140 kB
  • sloc: cpp: 21,984; f90: 3,707; sh: 966; ansic: 477; python: 389; makefile: 33
file content (127 lines) | stat: -rw-r--r-- 4,497 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
! To build this program, please make sure to reference linked libraries:
!
!     gfortran -lodccore -lfodc -o odc-fortran-header odc_header.f90

program odc_header
    use, intrinsic :: iso_fortran_env, only: error_unit,output_unit
    use odc
    implicit none

    character(255) :: path
    type(odc_reader) :: reader
    type(odc_frame) :: frame
    integer(8), target :: nrows
    integer :: err, narg, nframe
    integer :: nproperties, idx
    character(:), allocatable, target :: key, val
    character(:), allocatable, target :: name, type_name, bf_name
    integer, target :: ncols, col, type, element_size, bitfield_count
    integer, target :: bf, bf_offset, bf_size

    if (command_argument_count() < 1) then
        call usage()
        stop 1
    end if

    ! Initialise API
    call check_call(odc_initialise_api(), 'initialising api')

    ! Iterate over all supplied path arguments
    do narg = 1, command_argument_count()
        call get_command_argument(narg, path)

        ! Open current path and initialise frame
        call check_call(reader%open_path(trim(path)), 'opening path')
        call check_call(frame%initialise(reader), 'initialising frame')

        write(output_unit, '(a,a)') 'File: ', trim(path)
        flush(output_unit)

        nframe = 1

        ! Advance to the first frame in the stream in non-aggregated mode
        err = frame%next()

        do while (err == ODC_SUCCESS)

            ! Get row and column counts
            call check_call(frame%row_count(nrows), 'getting row count')
            call check_call(frame%column_count(ncols), 'getting column count')

            write(output_unit, '(a,i0,a,i0,a,i0)') '  Frame: ', nframe, ', Row count: ', nrows, &
                ', Column count: ', ncols
            flush(output_unit)

            ! Get number of properties encoded in the frame
            call check_call(frame%properties_count(nproperties), 'getting property count')

            do idx = 1, nproperties

                ! Get property key and value by its index
                call check_call(frame%property_idx(idx, key, val), 'getting property by index')

                write(output_unit, '(a,a,a,a)') '  Property: ', key, ' => ', val
            end do

            ! Iterate over frame columns
            do col = 1, ncols

                ! Get column information
                call check_call(frame%column_attributes(col, name, type, element_size, bitfield_count=bitfield_count), &
                    'getting column attributes')

                ! Lookup column type name
                call check_call(odc_column_type_name(type, type_name), 'getting column type name')

                write(output_unit, '(a,i0,a,a,a,a,a,i0)') '    Column: ', col, ', Name: ', name, &
                    ', Type: ', type_name, ', Size: ', element_size
                flush(output_unit)

                ! Process bitfields only
                if (type == ODC_BITFIELD) then
                    do bf = 1, bitfield_count

                        ! Get bitfield information
                        call check_call(frame%bitfield_attributes(col, bf, bf_name, bf_offset, bf_size), &
                            'getting bitfield attributes')

                        write(output_unit, '(a,i0,a,a,a,i0,a,i0)') '      Bitfield: ', bf, ', Name: ', bf_name, &
                            ', Offset: ', bf_offset, ', Nbits: ', bf_size
                        flush(output_unit)
                    end do
                end if
            end do

            nframe = nframe + 1
            write(output_unit, '(a)') ''
            flush(output_unit)

            ! Advances to the next frame in the stream in non-aggregated mode
            err = frame%next()
        end do

        if (err /= ODC_ITERATION_COMPLETE) call check_call(err, "get next frame")

        call check_call(reader%close(), "closing reader")
    end do

contains

    subroutine check_call(err, desc)
        integer, intent(in) :: err
        character(*), intent(in) :: desc

        if (err /= ODC_SUCCESS) then
            write(error_unit, *) '**** An error occurred in ODC library'
            write(error_unit, *) 'Description: ', desc
            write(error_unit, *) 'Error: ', odc_error_string(err)
            stop 1
        end if
    end subroutine

    subroutine usage()
        write(output_unit, *) 'Usage:'
        write(output_unit, *) '    odc-fortran-header <odb2 file 1> [<odb2 file 2> ...]'
    end subroutine

end program