1 | module m_dictionary |
---|
2 | |
---|
3 | use m_buffer |
---|
4 | private |
---|
5 | ! |
---|
6 | ! A very rough implementation for now |
---|
7 | ! It uses fixed-length buffers for key/value pairs, |
---|
8 | ! and the maximum number of dictionary items is hardwired. |
---|
9 | |
---|
10 | integer, parameter, private :: MAX_ITEMS = 64 |
---|
11 | type, public :: dictionary_t |
---|
12 | private |
---|
13 | integer :: number_of_items |
---|
14 | type(buffer_t), dimension(MAX_ITEMS) :: key |
---|
15 | type(buffer_t), dimension(MAX_ITEMS) :: value |
---|
16 | end type dictionary_t |
---|
17 | |
---|
18 | ! |
---|
19 | ! Building procedures |
---|
20 | ! |
---|
21 | public :: add_key_to_dict, add_value_to_dict, init_dict, reset_dict |
---|
22 | |
---|
23 | ! |
---|
24 | ! Query and extraction procedures |
---|
25 | ! |
---|
26 | public :: len |
---|
27 | interface len |
---|
28 | module procedure number_of_entries |
---|
29 | end interface |
---|
30 | public :: number_of_entries |
---|
31 | public :: get_key |
---|
32 | public :: get_value |
---|
33 | public :: has_key |
---|
34 | public :: print_dict |
---|
35 | ! |
---|
36 | public :: get_name |
---|
37 | |
---|
38 | interface get_name |
---|
39 | module procedure get_key |
---|
40 | end interface |
---|
41 | |
---|
42 | interface get_value |
---|
43 | module procedure sax_get_value |
---|
44 | end interface |
---|
45 | private :: sax_get_value |
---|
46 | |
---|
47 | CONTAINS |
---|
48 | |
---|
49 | !------------------------------------------------------ |
---|
50 | function number_of_entries(dict) result(n) |
---|
51 | type(dictionary_t), intent(in) :: dict |
---|
52 | integer :: n |
---|
53 | |
---|
54 | n = dict%number_of_items |
---|
55 | |
---|
56 | end function number_of_entries |
---|
57 | |
---|
58 | !------------------------------------------------------ |
---|
59 | function has_key(dict,key) result(found) |
---|
60 | type(dictionary_t), intent(in) :: dict |
---|
61 | character(len=*), intent(in) :: key |
---|
62 | logical :: found |
---|
63 | |
---|
64 | integer :: n, i |
---|
65 | found = .false. |
---|
66 | n = dict%number_of_items |
---|
67 | do i = 1, n |
---|
68 | if (dict%key(i) .EQUAL. key) then |
---|
69 | found = .true. |
---|
70 | exit |
---|
71 | endif |
---|
72 | enddo |
---|
73 | end function has_key |
---|
74 | |
---|
75 | !------------------------------------------------------ |
---|
76 | subroutine sax_get_value(dict,key,value,status) |
---|
77 | type(dictionary_t), intent(in) :: dict |
---|
78 | character(len=*), intent(in) :: key |
---|
79 | character(len=*), intent(out) :: value |
---|
80 | integer, intent(out) :: status |
---|
81 | ! |
---|
82 | integer :: n, i |
---|
83 | |
---|
84 | status = -1 |
---|
85 | n = dict%number_of_items |
---|
86 | do i = 1, n |
---|
87 | if (dict%key(i) .EQUAL. key) then |
---|
88 | value = str(dict%value(i)) |
---|
89 | status = 0 |
---|
90 | RETURN |
---|
91 | endif |
---|
92 | enddo |
---|
93 | |
---|
94 | end subroutine sax_get_value |
---|
95 | |
---|
96 | !------------------------------------------------------ |
---|
97 | subroutine get_key(dict,i,key,status) |
---|
98 | ! |
---|
99 | ! Get the i'th key |
---|
100 | ! |
---|
101 | type(dictionary_t), intent(in) :: dict |
---|
102 | integer, intent(in) :: i |
---|
103 | character(len=*), intent(out) :: key |
---|
104 | integer, intent(out) :: status |
---|
105 | |
---|
106 | if (i <= dict%number_of_items) then |
---|
107 | key = str(dict%key(i)) |
---|
108 | status = 0 |
---|
109 | else |
---|
110 | key = "" |
---|
111 | status = -1 |
---|
112 | endif |
---|
113 | |
---|
114 | end subroutine get_key |
---|
115 | |
---|
116 | !------------------------------------------------------ |
---|
117 | subroutine add_key_to_dict(key,dict) |
---|
118 | type(buffer_t), intent(in) :: key |
---|
119 | type(dictionary_t), intent(inout) :: dict |
---|
120 | |
---|
121 | integer :: n |
---|
122 | |
---|
123 | n = dict%number_of_items |
---|
124 | if (n == MAX_ITEMS) then |
---|
125 | write(unit=0,fmt=*) "Dictionary capacity exceeded ! size= ", max_items |
---|
126 | RETURN |
---|
127 | endif |
---|
128 | |
---|
129 | n = n + 1 |
---|
130 | dict%key(n) = key |
---|
131 | dict%number_of_items = n |
---|
132 | |
---|
133 | end subroutine add_key_to_dict |
---|
134 | |
---|
135 | !------------------------------------------------------ |
---|
136 | ! Assumes we build the dictionary in an orderly fashion, |
---|
137 | ! so one adds first the key and then immediately afterwards the value. |
---|
138 | ! |
---|
139 | subroutine add_value_to_dict(value,dict) |
---|
140 | type(buffer_t), intent(in) :: value |
---|
141 | type(dictionary_t), intent(inout) :: dict |
---|
142 | |
---|
143 | integer :: n |
---|
144 | |
---|
145 | n = dict%number_of_items |
---|
146 | dict%value(n) = value |
---|
147 | |
---|
148 | end subroutine add_value_to_dict |
---|
149 | |
---|
150 | !------------------------------------------------------ |
---|
151 | subroutine init_dict(dict) |
---|
152 | type(dictionary_t), intent(inout) :: dict |
---|
153 | |
---|
154 | integer :: i |
---|
155 | |
---|
156 | dict%number_of_items = 0 |
---|
157 | do i=1, MAX_ITEMS ! To avoid "undefined" status |
---|
158 | call init_buffer(dict%key(i)) ! (Fortran90 restriction) |
---|
159 | call init_buffer(dict%value(i)) |
---|
160 | enddo |
---|
161 | end subroutine init_dict |
---|
162 | !------------------------------------------------------ |
---|
163 | subroutine reset_dict(dict) |
---|
164 | type(dictionary_t), intent(inout) :: dict |
---|
165 | |
---|
166 | dict%number_of_items = 0 |
---|
167 | |
---|
168 | end subroutine reset_dict |
---|
169 | |
---|
170 | !------------------------------------------------------ |
---|
171 | subroutine print_dict(dict) |
---|
172 | type(dictionary_t), intent(in) :: dict |
---|
173 | |
---|
174 | integer :: i |
---|
175 | |
---|
176 | do i = 1, dict%number_of_items |
---|
177 | print *, trim(str(dict%key(i))), " = ", trim(str(dict%value(i))) |
---|
178 | enddo |
---|
179 | |
---|
180 | end subroutine print_dict |
---|
181 | |
---|
182 | |
---|
183 | end module m_dictionary |
---|