metkitlib 1.16.0.9__cp312-cp312-manylinux_2_28_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- metkitlib/__init__.py +3 -0
- metkitlib/bin/bufr-sanity-check +0 -0
- metkitlib/bin/compare-mars-requests.py +265 -0
- metkitlib/bin/mars-archive-script +0 -0
- metkitlib/bin/parse-mars-request +0 -0
- metkitlib/include/metkit/api/metkit_c.h +255 -0
- metkitlib/include/metkit/codes/BUFRDecoder.h +47 -0
- metkitlib/include/metkit/codes/BufrContent.h +43 -0
- metkitlib/include/metkit/codes/CodesContent.h +67 -0
- metkitlib/include/metkit/codes/CodesHandleDeleter.h +41 -0
- metkitlib/include/metkit/codes/CodesSplitter.h +40 -0
- metkitlib/include/metkit/codes/GRIBDecoder.h +42 -0
- metkitlib/include/metkit/codes/GribAccessor.h +75 -0
- metkitlib/include/metkit/codes/GribHandle.h +121 -0
- metkitlib/include/metkit/codes/GribIterator.h +48 -0
- metkitlib/include/metkit/codes/LibEccodes.h +38 -0
- metkitlib/include/metkit/codes/MallocCodesContent.h +46 -0
- metkitlib/include/metkit/codes/api/CodesAPI.h +365 -0
- metkitlib/include/metkit/codes/api/CodesTypes.h +93 -0
- metkitlib/include/metkit/codes/api/GeoIterator.h +104 -0
- metkitlib/include/metkit/codes/api/KeyIterator.h +187 -0
- metkitlib/include/metkit/config/LibMetkit.h +56 -0
- metkitlib/include/metkit/fields/FieldIndex.h +58 -0
- metkitlib/include/metkit/fields/FieldIndexList.h +40 -0
- metkitlib/include/metkit/fields/SimpleFieldIndex.h +41 -0
- metkitlib/include/metkit/hypercube/HyperCube.h +105 -0
- metkitlib/include/metkit/hypercube/HyperCubePayloaded.h +88 -0
- metkitlib/include/metkit/mars/BaseProtocol.h +95 -0
- metkitlib/include/metkit/mars/ClientTask.h +206 -0
- metkitlib/include/metkit/mars/DHSProtocol.h +106 -0
- metkitlib/include/metkit/mars/MarsExpandContext.h +42 -0
- metkitlib/include/metkit/mars/MarsExpansion.h +83 -0
- metkitlib/include/metkit/mars/MarsExpension.h +28 -0
- metkitlib/include/metkit/mars/MarsHandle.h +83 -0
- metkitlib/include/metkit/mars/MarsLanguage.h +106 -0
- metkitlib/include/metkit/mars/MarsLocation.h +100 -0
- metkitlib/include/metkit/mars/MarsParsedRequest.h +44 -0
- metkitlib/include/metkit/mars/MarsParser.h +70 -0
- metkitlib/include/metkit/mars/MarsRequest.h +198 -0
- metkitlib/include/metkit/mars/MarsRequestHandle.h +79 -0
- metkitlib/include/metkit/mars/Matcher.h +88 -0
- metkitlib/include/metkit/mars/Param.b +43 -0
- metkitlib/include/metkit/mars/Param.h +84 -0
- metkitlib/include/metkit/mars/ParamID.h +306 -0
- metkitlib/include/metkit/mars/Parameter.h +87 -0
- metkitlib/include/metkit/mars/Quantile.h +73 -0
- metkitlib/include/metkit/mars/RequestEnvironment.h +58 -0
- metkitlib/include/metkit/mars/StepRange.b +43 -0
- metkitlib/include/metkit/mars/StepRange.h +164 -0
- metkitlib/include/metkit/mars/StepRangeNormalise.h +95 -0
- metkitlib/include/metkit/mars/Type.h +265 -0
- metkitlib/include/metkit/mars/TypeAny.h +39 -0
- metkitlib/include/metkit/mars/TypeDate.h +42 -0
- metkitlib/include/metkit/mars/TypeEnum.h +67 -0
- metkitlib/include/metkit/mars/TypeExpver.h +40 -0
- metkitlib/include/metkit/mars/TypeFloat.h +41 -0
- metkitlib/include/metkit/mars/TypeInteger.h +55 -0
- metkitlib/include/metkit/mars/TypeLowercase.h +38 -0
- metkitlib/include/metkit/mars/TypeMixed.h +47 -0
- metkitlib/include/metkit/mars/TypeParam.h +45 -0
- metkitlib/include/metkit/mars/TypeRange.h +41 -0
- metkitlib/include/metkit/mars/TypeRegex.h +49 -0
- metkitlib/include/metkit/mars/TypeTime.h +44 -0
- metkitlib/include/metkit/mars/TypeToByList.h +137 -0
- metkitlib/include/metkit/mars/TypeToByListQuantile.h +41 -0
- metkitlib/include/metkit/mars/TypesFactory.h +92 -0
- metkitlib/include/metkit/metkit_config.h +26 -0
- metkitlib/include/metkit/metkit_ecbuild_config.h +72 -0
- metkitlib/include/metkit/metkit_version.h +30 -0
- metkitlib/include/metkit/pointdb/DataSource.h +91 -0
- metkitlib/include/metkit/pointdb/FieldIndexer.h +128 -0
- metkitlib/include/metkit/pointdb/GribDataSource.h +47 -0
- metkitlib/include/metkit/pointdb/GribFieldInfo.h +76 -0
- metkitlib/include/metkit/pointdb/GribHandleDataSource.h +58 -0
- metkitlib/include/metkit/pointdb/PointIndex.h +121 -0
- metkitlib/include/metkit/pointdb/bits.h +1834 -0
- metkitlib/include/metkit/pointdb/masks.h +22 -0
- metkitlib/include/metkit/tool/MetkitTool.h +79 -0
- metkitlib/lib64/cmake/metkit/metkit-config-version.cmake +43 -0
- metkitlib/lib64/cmake/metkit/metkit-config.cmake +112 -0
- metkitlib/lib64/cmake/metkit/metkit-import.cmake +14 -0
- metkitlib/lib64/cmake/metkit/metkit-targets-relwithdebinfo.cmake +46 -0
- metkitlib/lib64/cmake/metkit/metkit-targets.cmake +116 -0
- metkitlib/lib64/libmetkit.so +0 -0
- metkitlib/lib64/pkgconfig/metkit.pc +33 -0
- metkitlib/share/metkit/axis.yaml +63 -0
- metkitlib/share/metkit/bufr-subtypes.yaml +140 -0
- metkitlib/share/metkit/chemids.yaml +209 -0
- metkitlib/share/metkit/language.yaml +1707 -0
- metkitlib/share/metkit/modifiers.yaml +341 -0
- metkitlib/share/metkit/obstype.yaml +182 -0
- metkitlib/share/metkit/odb/marsrequest.yaml +9 -0
- metkitlib/share/metkit/param-matching.yaml +16 -0
- metkitlib/share/metkit/paramids.yaml +24034 -0
- metkitlib/share/metkit/params-static.yaml +212 -0
- metkitlib/share/metkit/params.yaml +9833 -0
- metkitlib/share/metkit/reportype.yaml +525 -0
- metkitlib/share/metkit/shortname-context.yaml +192 -0
- metkitlib-1.16.0.9.dist-info/METADATA +75 -0
- metkitlib-1.16.0.9.dist-info/RECORD +104 -0
- metkitlib-1.16.0.9.dist-info/WHEEL +5 -0
- metkitlib-1.16.0.9.dist-info/licenses/AUTHORS +12 -0
- metkitlib-1.16.0.9.dist-info/licenses/LICENSE +190 -0
- metkitlib-1.16.0.9.dist-info/top_level.txt +1 -0
metkitlib/__init__.py
ADDED
|
Binary file
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
# (C) Copyright 1996- ECMWF.
|
|
4
|
+
|
|
5
|
+
# This software is licensed under the terms of the Apache Licence Version 2.0
|
|
6
|
+
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
|
|
7
|
+
# In applying this licence, ECMWF does not waive the privileges and immunities
|
|
8
|
+
# granted to it by virtue of its status as an intergovernmental organisation nor
|
|
9
|
+
# does it submit to any jurisdiction.
|
|
10
|
+
|
|
11
|
+
# Emanuele Danovaro - ECMWF May 2021
|
|
12
|
+
|
|
13
|
+
import sys
|
|
14
|
+
import os.path
|
|
15
|
+
import json
|
|
16
|
+
import datetime
|
|
17
|
+
from dateutil.parser import parse
|
|
18
|
+
|
|
19
|
+
def check_one(name, old, new):
|
|
20
|
+
assert len(old) == 1 and len(new) == 1, f"{name.upper()}: too many values {len(old)} and {len(new)}"
|
|
21
|
+
return old[0], new[0]
|
|
22
|
+
|
|
23
|
+
def check_atMostOne(name, old, new):
|
|
24
|
+
assert len(old) < 2 and len(new) < 2, f"{name.upper()}: too many values {len(old)} and {len(new)}"
|
|
25
|
+
return old[0] if 0 < len(old) else None, new[0] if 0 < len(new) else None
|
|
26
|
+
|
|
27
|
+
def compare_int(name, old, new):
|
|
28
|
+
for o, n in zip(old, new):
|
|
29
|
+
assert str(o).isnumeric() and str(n).isnumeric() and int(o) == int(n), f"{name.upper()}: value mismatch '{old}' and '{new}'"
|
|
30
|
+
|
|
31
|
+
def compare_float(name, old, new):
|
|
32
|
+
for o, n in zip(old, new):
|
|
33
|
+
try:
|
|
34
|
+
o = float(o)
|
|
35
|
+
except ValueError:
|
|
36
|
+
o = o.lower()
|
|
37
|
+
|
|
38
|
+
try:
|
|
39
|
+
n = float(n)
|
|
40
|
+
except ValueError:
|
|
41
|
+
n = n.lower()
|
|
42
|
+
|
|
43
|
+
assert o == n, f"{name.upper()}: value mismatch '{old}' and '{new}'"
|
|
44
|
+
|
|
45
|
+
def compare_intAndKeywords(name, old, new, keywords):
|
|
46
|
+
o, n = check_atMostOne(name, old, new)
|
|
47
|
+
if o in keywords or str(o).lower() in keywords:
|
|
48
|
+
o = str(o).lower() if isinstance(o, str) else None
|
|
49
|
+
if n in keywords or str(n).lower() in keywords:
|
|
50
|
+
n = str(n).lower() if isinstance(n, str) else None
|
|
51
|
+
assert o == n or (str(o).isnumeric() and str(n).isnumeric() and int(o) == int(n)), f"{name.upper()}: value mismatch '{old}' and '{new}'"
|
|
52
|
+
|
|
53
|
+
def compare_grid(name, old, new):
|
|
54
|
+
for o, n in zip(old, new):
|
|
55
|
+
try:
|
|
56
|
+
o = float(o)
|
|
57
|
+
except ValueError:
|
|
58
|
+
o = o.lower()
|
|
59
|
+
|
|
60
|
+
try:
|
|
61
|
+
n = float(n)
|
|
62
|
+
except ValueError:
|
|
63
|
+
n = n.lower()
|
|
64
|
+
assert o == n, f"{name.upper()}: value mismatch '{old}' and '{new}'"
|
|
65
|
+
|
|
66
|
+
def compare_expect(name, old, new):
|
|
67
|
+
# 'any' or a positive integer value
|
|
68
|
+
compare_intAndKeywords(name, old, new, ["any"])
|
|
69
|
+
|
|
70
|
+
def compare_accuracy(name, old, new):
|
|
71
|
+
# 'off', 'av' or a positive integer value
|
|
72
|
+
compare_intAndKeywords(name, old, new, [None, "off", "av", "n"])
|
|
73
|
+
|
|
74
|
+
def compare_frame(name, old, new):
|
|
75
|
+
# 'off' or a positive integer value
|
|
76
|
+
compare_intAndKeywords(name, old, new, ["off"])
|
|
77
|
+
|
|
78
|
+
def compare_truncation(name, old, new):
|
|
79
|
+
# 'none', 'auto', 'off' or a positive integer value
|
|
80
|
+
compare_intAndKeywords(name, old, new, ["off", "none", "auto"])
|
|
81
|
+
|
|
82
|
+
def compare_step(name, old, new):
|
|
83
|
+
for o, n in zip(old, new):
|
|
84
|
+
oParts = str(o).split('-')
|
|
85
|
+
nParts = str(n).split('-')
|
|
86
|
+
assert len(oParts) == len(nParts) and all(float(oi) == float(ni) for oi, ni in zip(oParts, nParts)), f"{name.upper()}: value mismatch '{old}' and '{new}'"
|
|
87
|
+
|
|
88
|
+
def compare_str(name, old, new):
|
|
89
|
+
o, n = check_one(name, old, new)
|
|
90
|
+
assert o.replace('"', '').lower() == n.replace('"', '').lower(), f"{name.upper()}: string mismatch '{old[0]}' and '{new[0]}'"
|
|
91
|
+
|
|
92
|
+
def compare_strList(name, old, new):
|
|
93
|
+
for o, n in zip(old, new):
|
|
94
|
+
compare_str(name, [o], [n])
|
|
95
|
+
|
|
96
|
+
def compare_strCaseSensitive(name, old, new):
|
|
97
|
+
for o, n in zip(old, new):
|
|
98
|
+
assert o.replace('"', '') == n.replace('"', ''), f"{name.upper()}: string mismatch '{old}' and '{new}'"
|
|
99
|
+
|
|
100
|
+
def compare_time(name, old, new):
|
|
101
|
+
o, n = check_one(name, old, new)
|
|
102
|
+
|
|
103
|
+
if isinstance(o, str):
|
|
104
|
+
o = int(o.replace(':', ''))
|
|
105
|
+
if o>9999:
|
|
106
|
+
o = o/100
|
|
107
|
+
|
|
108
|
+
if isinstance(n, str):
|
|
109
|
+
n = int(n.replace(':', ''))
|
|
110
|
+
if n > 9999:
|
|
111
|
+
n = n / 100
|
|
112
|
+
|
|
113
|
+
assert o == n, f"{name.upper()}: time mismatch '{old[0]}' and '{new[0]}'"
|
|
114
|
+
|
|
115
|
+
def compare_date(name, old, new):
|
|
116
|
+
o, n = check_one(name, old, new)
|
|
117
|
+
oStart = parse(str(o), default=datetime.datetime(1901, 1, 1))
|
|
118
|
+
oEnd = parse(str(o), default=datetime.datetime(2001, 12, 31))
|
|
119
|
+
nStart = parse(str(n), default=datetime.datetime(1901, 1, 1))
|
|
120
|
+
nEnd = parse(str(n), default=datetime.datetime(2001, 12, 31))
|
|
121
|
+
assert oStart.date() == nStart.date() and oEnd.date() == nEnd.date(), f"{name.upper()}: date mismatch '{old[0]}' and '{new[0]}'"
|
|
122
|
+
|
|
123
|
+
def compare_dates(name, old, new):
|
|
124
|
+
for o, n in zip(old, new):
|
|
125
|
+
oStart = parse(str(o), default=datetime.datetime(1901, 1, 1))
|
|
126
|
+
oEnd = parse(str(o), default=datetime.datetime(2001, 12, 31))
|
|
127
|
+
nStart = parse(str(n), default=datetime.datetime(1901, 1, 1))
|
|
128
|
+
nEnd = parse(str(n), default=datetime.datetime(2001, 12, 31))
|
|
129
|
+
assert oStart.date() == nStart.date() and oEnd.date() == nEnd.date(), f"{name.upper()}: date mismatch '{o}' and '{n}'"
|
|
130
|
+
|
|
131
|
+
def compare_expver(name, old, new):
|
|
132
|
+
o, n = check_one(name, old, new)
|
|
133
|
+
if isinstance(o, str):
|
|
134
|
+
try:
|
|
135
|
+
o = int(o)
|
|
136
|
+
except ValueError:
|
|
137
|
+
o = o.lower()
|
|
138
|
+
|
|
139
|
+
if isinstance(n, str):
|
|
140
|
+
try:
|
|
141
|
+
n = int(n)
|
|
142
|
+
except ValueError:
|
|
143
|
+
n = n.lower()
|
|
144
|
+
|
|
145
|
+
assert o == n, f"{name.upper()}: mismatch '{old[0]}' and '{new[0]}'"
|
|
146
|
+
|
|
147
|
+
def ignore(name, old, new):
|
|
148
|
+
pass
|
|
149
|
+
|
|
150
|
+
def ignore_fixYaml(name, old, new):
|
|
151
|
+
pass
|
|
152
|
+
|
|
153
|
+
comparators = {
|
|
154
|
+
"accuracy": ignore_fixYaml, # ?????
|
|
155
|
+
# "accuracy": compare_accuracy,
|
|
156
|
+
"anoffset": compare_int, # ?????
|
|
157
|
+
"area": ignore_fixYaml,
|
|
158
|
+
"bitmap": compare_strCaseSensitive,
|
|
159
|
+
# block
|
|
160
|
+
# channel
|
|
161
|
+
"class": compare_str,
|
|
162
|
+
"database": compare_str, # ?????
|
|
163
|
+
"date": compare_date,
|
|
164
|
+
"diagnostic": compare_int, # ??????
|
|
165
|
+
"direction": compare_int, # should we handle case "all"
|
|
166
|
+
"domain": compare_str,
|
|
167
|
+
"duplicates": compare_str, # can we ignore ?
|
|
168
|
+
"expect": compare_expect,
|
|
169
|
+
"expver": compare_expver,
|
|
170
|
+
"fcmonth": compare_int,
|
|
171
|
+
"fcperiod": compare_step, # ??????
|
|
172
|
+
"fieldset": compare_strCaseSensitive,
|
|
173
|
+
"filter": compare_str,
|
|
174
|
+
"format": compare_str, # ?????
|
|
175
|
+
"frame": compare_frame,
|
|
176
|
+
"frequency": compare_int, # ??????
|
|
177
|
+
"grid": compare_grid,
|
|
178
|
+
"hdate": compare_dates,
|
|
179
|
+
"ident": compare_int,
|
|
180
|
+
"interpolation": compare_str,
|
|
181
|
+
# "intgrid":
|
|
182
|
+
"iteration": compare_int, # ??????
|
|
183
|
+
"latitude": compare_float,
|
|
184
|
+
"levelist": compare_float,
|
|
185
|
+
"levtype": compare_str,
|
|
186
|
+
"longitude": compare_float,
|
|
187
|
+
"lsm": compare_str, # ?????
|
|
188
|
+
"method": compare_int,
|
|
189
|
+
"number": compare_int,
|
|
190
|
+
"obsgroup": compare_str, # ?????
|
|
191
|
+
"obstype": compare_int,
|
|
192
|
+
"origin": compare_expver, # ?????
|
|
193
|
+
"packing": compare_str,
|
|
194
|
+
"padding": compare_int, # ??????
|
|
195
|
+
"param": compare_float, # <-- to check that short names have been replaced, otherwise we can use compare_strList
|
|
196
|
+
"priority": compare_int,
|
|
197
|
+
"product": compare_str, # ?????
|
|
198
|
+
"range": compare_int,
|
|
199
|
+
"refdate": compare_date,
|
|
200
|
+
"reference": compare_int,
|
|
201
|
+
"reportype": compare_int,
|
|
202
|
+
"repres": ignore,
|
|
203
|
+
# resol
|
|
204
|
+
"rotation": compare_grid,
|
|
205
|
+
"section": compare_str,
|
|
206
|
+
"source": compare_strCaseSensitive,
|
|
207
|
+
"step": compare_step,
|
|
208
|
+
"stream": compare_str,
|
|
209
|
+
"system": compare_int,
|
|
210
|
+
"target": compare_strCaseSensitive,
|
|
211
|
+
"time": compare_time,
|
|
212
|
+
"truncation": compare_truncation,
|
|
213
|
+
"type": compare_str,
|
|
214
|
+
"use": compare_str
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
def compare(name, old, new):
|
|
218
|
+
if not isinstance(old, list):
|
|
219
|
+
old = [old]
|
|
220
|
+
if not isinstance(new, list):
|
|
221
|
+
new = [new]
|
|
222
|
+
|
|
223
|
+
assert len(old) == len(new), f"{name}: list mismatch {len(old)} and {len(new)}"
|
|
224
|
+
assert name in comparators.keys(), f"{name}: not supported"
|
|
225
|
+
comparators[name](name, old, new)
|
|
226
|
+
|
|
227
|
+
# compare_date('date', '20210501', '2021-05-01')
|
|
228
|
+
# compare_date('date', '20210501', '2021-May-01')
|
|
229
|
+
# compare_date('date', '20210501', '2021-may-01')
|
|
230
|
+
# compare_date('date', 'May-1', 'may-01')
|
|
231
|
+
# compare_date('date', 'May', 'may')
|
|
232
|
+
# compare_date('date', 'May', '20210521')
|
|
233
|
+
|
|
234
|
+
# check command line parameters
|
|
235
|
+
if len(sys.argv) != 3 or not os.path.isfile(sys.argv[1]) or not os.path.isfile(sys.argv[2]):
|
|
236
|
+
print('Please specify the json files to be compared.')
|
|
237
|
+
print('Usage: ',sys.argv[0], '<first.json> <second.json>')
|
|
238
|
+
if len(sys.argv)>1 and not os.path.isfile(sys.argv[1]):
|
|
239
|
+
print(sys.argv[1], 'is not a file')
|
|
240
|
+
if len(sys.argv)>2 and not os.path.isfile(sys.argv[2]):
|
|
241
|
+
print(sys.argv[2], 'is not a file')
|
|
242
|
+
exit(1)
|
|
243
|
+
|
|
244
|
+
#open json files and build case insensitive dictionaries
|
|
245
|
+
json_lines_1 = []
|
|
246
|
+
with open(sys.argv[1]) as json_file:
|
|
247
|
+
for line in json_file:
|
|
248
|
+
j = {}
|
|
249
|
+
for key, value in json.loads(line).items():
|
|
250
|
+
j[key.lower()] = value
|
|
251
|
+
json_lines_1.append(j)
|
|
252
|
+
|
|
253
|
+
json_lines_2 = []
|
|
254
|
+
with open(sys.argv[2]) as json_file:
|
|
255
|
+
for line in json_file:
|
|
256
|
+
j = {}
|
|
257
|
+
for key, value in json.loads(line).items():
|
|
258
|
+
j[key.lower()] = value
|
|
259
|
+
json_lines_2.append(j)
|
|
260
|
+
|
|
261
|
+
assert len(json_lines_1) == len(json_lines_2), f"Json mismatch: {sys.argv[1]} contains {len(json_lines_1)} while {sys.argv[2]} contains {len(json_lines_2)}"
|
|
262
|
+
|
|
263
|
+
for j1, j2 in zip(json_lines_1, json_lines_2):
|
|
264
|
+
for key in set(j1.keys()) | set(j2.keys()):
|
|
265
|
+
compare(key, j1.get(key), j2.get(key))
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <stdbool.h>
|
|
4
|
+
#include <stddef.h>
|
|
5
|
+
|
|
6
|
+
#ifdef __cplusplus
|
|
7
|
+
extern "C" {
|
|
8
|
+
#endif
|
|
9
|
+
|
|
10
|
+
/* ---------------------------------------------------------------------------------------------------------------------
|
|
11
|
+
* TYPES
|
|
12
|
+
* -----*/
|
|
13
|
+
|
|
14
|
+
struct metkit_marsrequest_t;
|
|
15
|
+
typedef struct metkit_marsrequest_t metkit_marsrequest_t;
|
|
16
|
+
|
|
17
|
+
struct metkit_requestiterator_t;
|
|
18
|
+
/** RequestIterator for iterating over vector of Request instances */
|
|
19
|
+
typedef struct metkit_requestiterator_t metkit_requestiterator_t;
|
|
20
|
+
|
|
21
|
+
struct metkit_paramiterator_t;
|
|
22
|
+
/** Iterator for iterating over parameters in Request */
|
|
23
|
+
typedef struct metkit_paramiterator_t metkit_paramiterator_t;
|
|
24
|
+
|
|
25
|
+
/* ---------------------------------------------------------------------------------------------------------------------
|
|
26
|
+
* ERROR HANDLING
|
|
27
|
+
* -------------- */
|
|
28
|
+
|
|
29
|
+
typedef enum metkit_error_values_t {
|
|
30
|
+
METKIT_SUCCESS = 0, /* Operation succeded. */
|
|
31
|
+
METKIT_ERROR = 1, /* Operation failed. */
|
|
32
|
+
METKIT_ERROR_UNKNOWN = 2, /* Failed with an unknown error. */
|
|
33
|
+
METKIT_ERROR_USER = 3, /* Failed with an user error. */
|
|
34
|
+
METKIT_ERROR_ASSERT = 4 /* Failed with an assert() */
|
|
35
|
+
} metkit_error_t;
|
|
36
|
+
|
|
37
|
+
typedef enum metkit_iterator_status_t {
|
|
38
|
+
METKIT_ITERATOR_SUCCESS = 0, /* Operation succeded. */
|
|
39
|
+
METKIT_ITERATOR_COMPLETE = 1, /* All elements have been returned */
|
|
40
|
+
METKIT_ITERATOR_ERROR = 2 /* Operation failed. */
|
|
41
|
+
} metkit_iterator_status_t;
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
const char* metkit_get_error_string(enum metkit_error_values_t err);
|
|
45
|
+
|
|
46
|
+
/* -----------------------------------------------------------------------------
|
|
47
|
+
* HELPERS
|
|
48
|
+
* ------- */
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @brief Get metkit version.
|
|
52
|
+
*
|
|
53
|
+
* @return const char* version string
|
|
54
|
+
*/
|
|
55
|
+
const char* metkit_version();
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @brief Get metkit git sha1 version.
|
|
59
|
+
*
|
|
60
|
+
* @return const char* git sha1 version string
|
|
61
|
+
*/
|
|
62
|
+
const char* metkit_git_sha1();
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @brief Initialise Main() context.
|
|
66
|
+
*
|
|
67
|
+
* @note This is ONLY required when Main() is NOT initialised, such as loading
|
|
68
|
+
* the MetKit as shared library in Python.
|
|
69
|
+
* @return metkit_error_t Error code
|
|
70
|
+
*/
|
|
71
|
+
metkit_error_t metkit_initialise();
|
|
72
|
+
|
|
73
|
+
/* ---------------------------------------------------------------------------------------------------------------------
|
|
74
|
+
* PARSING
|
|
75
|
+
* --- */
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Parse MARS requests into RequestIterator of Request instances. Resulting RequestIterator
|
|
79
|
+
* must be deallocated with metkit_delete_requestiterator
|
|
80
|
+
* @param str MARS requests
|
|
81
|
+
* @param[out] requests Allocates RequestIterator object
|
|
82
|
+
* @return metkit_error_t Error code
|
|
83
|
+
*/
|
|
84
|
+
metkit_error_t metkit_parse_marsrequests(const char* str, metkit_requestiterator_t** requests, bool strict);
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Parse MARS request into Request instance
|
|
88
|
+
* @note will error if request expands to multiple requests: use metkit_parse_marsrequests instead
|
|
89
|
+
* @param str MARS request
|
|
90
|
+
* @param[out] request Request instance
|
|
91
|
+
* @param strict if true, raise error rather than warning on invalid values
|
|
92
|
+
* @return metkit_error_t Error code
|
|
93
|
+
*/
|
|
94
|
+
metkit_error_t metkit_parse_marsrequest(const char* str, metkit_marsrequest_t* request, bool strict);
|
|
95
|
+
/* ---------------------------------------------------------------------------------------------------------------------
|
|
96
|
+
* REQUEST
|
|
97
|
+
* --- */
|
|
98
|
+
|
|
99
|
+
/** Allocates new Request object. Must be deallocated with mekit_delete_request
|
|
100
|
+
* @param[out] request new Request instance
|
|
101
|
+
* @return metkit_error_t Error code
|
|
102
|
+
*/
|
|
103
|
+
metkit_error_t metkit_marsrequest_new(metkit_marsrequest_t** request);
|
|
104
|
+
|
|
105
|
+
/** Deallocates Request object and associated resources.
|
|
106
|
+
* @param request Request instance
|
|
107
|
+
* @return metkit_error_t Error code
|
|
108
|
+
*/
|
|
109
|
+
metkit_error_t metkit_marsrequest_delete(const metkit_marsrequest_t* request);
|
|
110
|
+
|
|
111
|
+
/** Add parameter and values to request
|
|
112
|
+
* @param request Request instance
|
|
113
|
+
* @param param parameter name
|
|
114
|
+
* @param values array of values for parameter
|
|
115
|
+
* @param numValues number of values
|
|
116
|
+
* @return metkit_error_t Error code
|
|
117
|
+
*/
|
|
118
|
+
metkit_error_t metkit_marsrequest_set(metkit_marsrequest_t* request, const char* param, const char* values[],
|
|
119
|
+
int numValues);
|
|
120
|
+
|
|
121
|
+
/** Add parameter and values to request
|
|
122
|
+
* @param request Request instance
|
|
123
|
+
* @param param parameter name
|
|
124
|
+
* @param values value to add
|
|
125
|
+
* @return metkit_error_t Error code
|
|
126
|
+
*/
|
|
127
|
+
metkit_error_t metkit_marsrequest_set_one(metkit_marsrequest_t* request, const char* param, const char* value);
|
|
128
|
+
|
|
129
|
+
/** Set verb in Request object
|
|
130
|
+
* @param request Request instance
|
|
131
|
+
* @param verb verb to set
|
|
132
|
+
* @return metkit_error_t Error code
|
|
133
|
+
*/
|
|
134
|
+
metkit_error_t metkit_marsrequest_set_verb(metkit_marsrequest_t* request, const char* verb);
|
|
135
|
+
|
|
136
|
+
/** Returns the verb in Request object
|
|
137
|
+
* @param request Request instance
|
|
138
|
+
* @param[out] verb verb in request
|
|
139
|
+
* @return metkit_error_t Error code
|
|
140
|
+
*/
|
|
141
|
+
metkit_error_t metkit_marsrequest_verb(const metkit_marsrequest_t* request, const char** verb);
|
|
142
|
+
|
|
143
|
+
/** Returns whether parameter is in Request object
|
|
144
|
+
* @param request Request instance
|
|
145
|
+
* @param param parameter name
|
|
146
|
+
* @param[out] has whether parameter exists in request
|
|
147
|
+
* @return metkit_error_t Error code
|
|
148
|
+
*/
|
|
149
|
+
metkit_error_t metkit_marsrequest_has_param(const metkit_marsrequest_t* request, const char* param, bool* has);
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
/** Returns parameter iterator for Request object
|
|
153
|
+
* Must be deallocated with metkit_paramiterator_delete
|
|
154
|
+
* @note: The strings obtained from next() are owned by the iterator and should be copied if they need to outlive it.
|
|
155
|
+
* @param request Request instance
|
|
156
|
+
* @param[out] params parameter iterator
|
|
157
|
+
* @return metkit_error_t Error code
|
|
158
|
+
*/
|
|
159
|
+
metkit_error_t metkit_marsrequest_params(const metkit_marsrequest_t* request, metkit_paramiterator_t** params);
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
/** Returns number of values for specific parameter in Request object
|
|
163
|
+
* @param request Request instance
|
|
164
|
+
* @param param parameter name in request
|
|
165
|
+
* @param[out] count number of values for param in request
|
|
166
|
+
* @return metkit_error_t Error code
|
|
167
|
+
*/
|
|
168
|
+
metkit_error_t metkit_marsrequest_count_values(const metkit_marsrequest_t* request, const char* param, size_t* count);
|
|
169
|
+
|
|
170
|
+
/** Returns value for specific parameter and index in Request object
|
|
171
|
+
* @param request Request instance
|
|
172
|
+
* @param param parameter name in request
|
|
173
|
+
* @param index index of value to retrieve for param in request
|
|
174
|
+
* @param[out] value retrieved value
|
|
175
|
+
* @return metkit_error_t Error code
|
|
176
|
+
*/
|
|
177
|
+
metkit_error_t metkit_marsrequest_value(const metkit_marsrequest_t* request, const char* param, int index,
|
|
178
|
+
const char** value);
|
|
179
|
+
|
|
180
|
+
/** Populates empty Request object by expanding existing request
|
|
181
|
+
* @param request Request instance to be expanded
|
|
182
|
+
* @param inherit if true, populate expanded request with default values
|
|
183
|
+
* @param strict it true, raise error rather than warning on invalid values
|
|
184
|
+
* @param[out] expandedRequest empty Request instance to be populated
|
|
185
|
+
* @return metkit_error_t Error code
|
|
186
|
+
*/
|
|
187
|
+
metkit_error_t metkit_marsrequest_expand(const metkit_marsrequest_t* request, bool inherit, bool strict,
|
|
188
|
+
metkit_marsrequest_t* expandedRequest);
|
|
189
|
+
|
|
190
|
+
/** Merges other Request object into existing request
|
|
191
|
+
* @param request Request instance to contain result of merge
|
|
192
|
+
* @param otherRequest other Request instance to merge
|
|
193
|
+
* @return metkit_error_t Error code
|
|
194
|
+
*/
|
|
195
|
+
metkit_error_t metkit_marsrequest_merge(metkit_marsrequest_t* request, const metkit_marsrequest_t* otherRequest);
|
|
196
|
+
|
|
197
|
+
/* ---------------------------------------------------------------------------------------------------------------------
|
|
198
|
+
* REQUEST ITERATOR
|
|
199
|
+
* --- */
|
|
200
|
+
|
|
201
|
+
/** Deallocates RequestIterator object and associated resources.
|
|
202
|
+
* @param it RequestIterator instance
|
|
203
|
+
* @return metkit_error_t Error code
|
|
204
|
+
*/
|
|
205
|
+
metkit_error_t metkit_requestiterator_delete(const metkit_requestiterator_t* it);
|
|
206
|
+
|
|
207
|
+
/** Moves to the next Request element in RequestIterator
|
|
208
|
+
* @param it RequestIterator instance
|
|
209
|
+
* @return metkit_iterator_status_t Status of iterator
|
|
210
|
+
*/
|
|
211
|
+
// metkit_error_t metkit_requestiterator_next(metkit_requestiterator_t* it);
|
|
212
|
+
metkit_iterator_status_t metkit_requestiterator_next(metkit_requestiterator_t* it);
|
|
213
|
+
|
|
214
|
+
/** Populates empty Request object with data from current element in RequestIterator
|
|
215
|
+
* @param it RequestIterator instance
|
|
216
|
+
* @param request empty Request instance to populate with data
|
|
217
|
+
* @return metkit_iterator_status_t Status of iterator
|
|
218
|
+
* @note must call metkit_requestiterator_next before calling metkit_requestiterator_current.
|
|
219
|
+
*
|
|
220
|
+
* Example usage:
|
|
221
|
+
* while (metkit_requestiterator_next(it) == METKIT_ITERATOR_SUCCESS) {
|
|
222
|
+
* metkit_marsrequest_t* req{};
|
|
223
|
+
* metkit_marsrequest_new(&req);
|
|
224
|
+
* metkit_requestiterator_current(it, req);
|
|
225
|
+
* // use req ...
|
|
226
|
+
* }
|
|
227
|
+
*/
|
|
228
|
+
metkit_iterator_status_t metkit_requestiterator_current(metkit_requestiterator_t* it, metkit_marsrequest_t* request);
|
|
229
|
+
|
|
230
|
+
/* ---------------------------------------------------------------------------------------------------------------------
|
|
231
|
+
* PARAMETER ITERATOR
|
|
232
|
+
* --- */
|
|
233
|
+
|
|
234
|
+
/** Deallocates ParamIterator object and the char* strings it owns.
|
|
235
|
+
* @param it ParamIterator instance
|
|
236
|
+
* @return metkit_error_t Error code
|
|
237
|
+
*/
|
|
238
|
+
metkit_error_t metkit_paramiterator_delete(const metkit_paramiterator_t* it);
|
|
239
|
+
|
|
240
|
+
/** Moves to the next parameter in ParamIterator
|
|
241
|
+
* @param it ParamIterator instance
|
|
242
|
+
* @return metkit_iterator_status_t Status of iterator
|
|
243
|
+
*/
|
|
244
|
+
metkit_iterator_status_t metkit_paramiterator_next(metkit_paramiterator_t* it);
|
|
245
|
+
|
|
246
|
+
/** Returns current parameter in ParamIterator
|
|
247
|
+
* @param it ParamIterator instance
|
|
248
|
+
* @param[out] param current parameter
|
|
249
|
+
* @return metkit_iterator_status_t Status of iterator
|
|
250
|
+
*/
|
|
251
|
+
metkit_iterator_status_t metkit_paramiterator_current(const metkit_paramiterator_t* it, const char** param);
|
|
252
|
+
|
|
253
|
+
#ifdef __cplusplus
|
|
254
|
+
}
|
|
255
|
+
#endif
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* (C) Copyright 1996- ECMWF.
|
|
3
|
+
*
|
|
4
|
+
* This software is licensed under the terms of the Apache Licence Version 2.0
|
|
5
|
+
* which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
|
|
6
|
+
* In applying this licence, ECMWF does not waive the privileges and immunities
|
|
7
|
+
* granted to it by virtue of its status as an intergovernmental organisation nor
|
|
8
|
+
* does it submit to any jurisdiction.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/// @author Baudouin Raoult
|
|
12
|
+
/// @date Jun 2020
|
|
13
|
+
|
|
14
|
+
#pragma once
|
|
15
|
+
|
|
16
|
+
#include "eckit/message/Decoder.h"
|
|
17
|
+
#include "eckit/message/Message.h"
|
|
18
|
+
|
|
19
|
+
#include "eckit/io/Buffer.h"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
namespace metkit {
|
|
23
|
+
namespace codes {
|
|
24
|
+
|
|
25
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
26
|
+
|
|
27
|
+
class BUFRDecoder : public eckit::message::MessageDecoder {
|
|
28
|
+
|
|
29
|
+
public: // methods
|
|
30
|
+
|
|
31
|
+
static bool typeBySubtype(long subtype, long& type);
|
|
32
|
+
|
|
33
|
+
private: // methods
|
|
34
|
+
|
|
35
|
+
bool match(const eckit::message::Message&) const override;
|
|
36
|
+
void print(std::ostream&) const override;
|
|
37
|
+
|
|
38
|
+
void getMetadata(const eckit::message::Message& msg, eckit::message::MetadataGatherer&,
|
|
39
|
+
const eckit::message::GetMetadataOptions&) const override;
|
|
40
|
+
|
|
41
|
+
eckit::Buffer decode(const eckit::message::Message& msg) const override;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
45
|
+
|
|
46
|
+
} // namespace codes
|
|
47
|
+
} // namespace metkit
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* (C) Copyright 2017- ECMWF.
|
|
3
|
+
*
|
|
4
|
+
* This software is licensed under the terms of the Apache Licence Version 2.0
|
|
5
|
+
* which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
|
|
6
|
+
* In applying this licence, ECMWF does not waive the privileges and immunities
|
|
7
|
+
* granted to it by virtue of its status as an intergovernmental organisation nor
|
|
8
|
+
* does it submit to any jurisdiction.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/// @author Baudouin Raoult
|
|
12
|
+
/// @author Emanuele Danovaro
|
|
13
|
+
/// @date Mar 2022
|
|
14
|
+
|
|
15
|
+
#pragma once
|
|
16
|
+
|
|
17
|
+
#include "metkit/codes/CodesContent.h"
|
|
18
|
+
|
|
19
|
+
namespace metkit {
|
|
20
|
+
namespace codes {
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
class BufrContent : public CodesContent {
|
|
26
|
+
public:
|
|
27
|
+
|
|
28
|
+
BufrContent(codes_handle* handle, bool delete_handle);
|
|
29
|
+
explicit BufrContent(const codes_handle* handle);
|
|
30
|
+
|
|
31
|
+
~BufrContent();
|
|
32
|
+
|
|
33
|
+
protected:
|
|
34
|
+
|
|
35
|
+
using CodesContent::transform;
|
|
36
|
+
void transform(const eckit::OrderedStringDict& dict) override;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
} // namespace codes
|
|
43
|
+
} // namespace metkit
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* (C) Copyright 2017- ECMWF.
|
|
3
|
+
*
|
|
4
|
+
* This software is licensed under the terms of the Apache Licence Version 2.0
|
|
5
|
+
* which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
|
|
6
|
+
* In applying this licence, ECMWF does not waive the privileges and immunities
|
|
7
|
+
* granted to it by virtue of its status as an intergovernmental organisation nor
|
|
8
|
+
* does it submit to any jurisdiction.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/// @author Baudouin Raoult
|
|
12
|
+
/// @date Jun 2020
|
|
13
|
+
|
|
14
|
+
#pragma once
|
|
15
|
+
|
|
16
|
+
#include "eckit/message/MessageContent.h"
|
|
17
|
+
|
|
18
|
+
typedef struct grib_handle codes_handle;
|
|
19
|
+
|
|
20
|
+
namespace metkit {
|
|
21
|
+
namespace codes {
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
class CodesContent : public eckit::message::MessageContent {
|
|
27
|
+
public:
|
|
28
|
+
|
|
29
|
+
CodesContent(codes_handle* handle, bool delete_handle);
|
|
30
|
+
explicit CodesContent(const codes_handle* handle);
|
|
31
|
+
|
|
32
|
+
~CodesContent();
|
|
33
|
+
|
|
34
|
+
protected:
|
|
35
|
+
|
|
36
|
+
codes_handle* handle_;
|
|
37
|
+
|
|
38
|
+
using eckit::message::MessageContent::transform;
|
|
39
|
+
void transform(const eckit::OrderedStringDict&) override;
|
|
40
|
+
|
|
41
|
+
private:
|
|
42
|
+
|
|
43
|
+
bool delete_handle_;
|
|
44
|
+
|
|
45
|
+
size_t length() const override;
|
|
46
|
+
void write(eckit::DataHandle& handle) const override;
|
|
47
|
+
eckit::DataHandle* readHandle() const override;
|
|
48
|
+
void print(std::ostream& s) const override;
|
|
49
|
+
std::string getString(const std::string& key) const override;
|
|
50
|
+
long getLong(const std::string& key) const override;
|
|
51
|
+
double getDouble(const std::string& key) const override;
|
|
52
|
+
void getDoubleArray(const std::string& key, std::vector<double>& values) const override;
|
|
53
|
+
void getFloatArray(const std::string& key, std::vector<float>& values) const override;
|
|
54
|
+
size_t getSize(const std::string& key) const override;
|
|
55
|
+
void getDoubleArray(const std::string& key, double* data, size_t lenExpected) const override;
|
|
56
|
+
void getFloatArray(const std::string& key, float* data, size_t lenExpected) const override;
|
|
57
|
+
|
|
58
|
+
eckit::Offset offset() const override;
|
|
59
|
+
const codes_handle* codesHandle() const;
|
|
60
|
+
const void* data() const override;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
65
|
+
|
|
66
|
+
} // namespace codes
|
|
67
|
+
} // namespace metkit
|