Skip to content

Commit c381622

Browse files
authored
Merge pull request #127 from ecmwf/feature/METK-145-Replace-CodesDecoder
Replace CodesDecoder with CodesAPI
2 parents 882e7d7 + 574bb6b commit c381622

File tree

8 files changed

+72
-258
lines changed

8 files changed

+72
-258
lines changed

src/metkit/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,6 @@ if ( HAVE_GRIB )
125125
pointdb/masks.h
126126
pointdb/PointIndex.cc
127127
pointdb/PointIndex.h
128-
codes/CodesDecoder.h
129128
codes/BUFRDecoder.cc
130129
codes/BUFRDecoder.h
131130
codes/GRIBDecoder.cc

src/metkit/codes/BUFRDecoder.cc

Lines changed: 28 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,21 @@
88
* does it submit to any jurisdiction.
99
*/
1010

11-
#include "metkit/codes/CodesDecoder.h"
12-
1311
#include <cstring>
12+
#include <type_traits>
1413

1514
#include "eckit/config/Resource.h"
1615
#include "eckit/message/Message.h"
1716
#include "eckit/parser/YAMLParser.h"
1817

1918
#include "metkit/codes/BUFRDecoder.h"
20-
#include "metkit/codes/CodesHandleDeleter.h"
19+
#include "metkit/codes/api/CodesAPI.h"
20+
#include "metkit/codes/api/CodesTypes.h"
2121
#include "metkit/config/LibMetkit.h"
2222
#include "metkit/mars/MarsRequest.h"
2323

24+
#include "eckit/exception/Exceptions.h"
25+
2426
#include "eccodes.h"
2527

2628
namespace metkit {
@@ -69,43 +71,11 @@ bool BUFRDecoder::match(const eckit::message::Message& msg) const {
6971

7072
//----------------------------------------------------------------------------------------------------------------------
7173

72-
namespace {
73-
74-
// TODO In C++14: move to lambda with auto
75-
struct BUFRMetadataIt {
76-
codes_handle* h;
77-
codes_bufr_keys_iterator* itCtx;
78-
eckit::message::MetadataGatherer& gather;
79-
80-
template <typename DecFunc>
81-
void operator()(DecFunc&& decode) {
82-
while (codes_bufr_keys_iterator_next(itCtx)) {
83-
const char* name = codes_bufr_keys_iterator_get_name(itCtx);
84-
85-
if (std::strcmp(name, "subsetNumber") == 0) {
86-
continue;
87-
}
88-
89-
size_t klen = 0;
90-
91-
/* get key size to see if it is an array */
92-
ASSERT(codes_get_size(h, name, &klen) == 0);
93-
if (klen != 1) {
94-
continue;
95-
}
96-
decode(h, gather, name);
97-
}
98-
}
99-
};
100-
101-
} // namespace
102-
10374

10475
void BUFRDecoder::getMetadata(const eckit::message::Message& msg, eckit::message::MetadataGatherer& gather,
10576
const eckit::message::GetMetadataOptions& options) const {
10677

107-
std::unique_ptr<codes_handle> h(::codes_handle_new_from_message(nullptr, msg.data(), msg.length()));
108-
ASSERT(h);
78+
auto h(codesHandleFromMessage({static_cast<const uint8_t*>(msg.data()), msg.length()}));
10979

11080
/*
11181
// BUFR Performance improvement:
@@ -117,27 +87,37 @@ void BUFRDecoder::getMetadata(const eckit::message::Message& msg, eckit::message
11787

11888
// we need to instruct ecCodes to unpack the data values:
11989
// https://confluence.ecmwf.int/display/ECC/bufr_keys_iterator
120-
CODES_CHECK(codes_set_long(h.get(), "unpack", 1), 0);
90+
h->set("unpack", 1);
12191

122-
std::unique_ptr<codes_bufr_keys_iterator> itCtx(::codes_bufr_keys_iterator_new(h.get(), 0));
123-
ASSERT(itCtx);
92+
for (auto& k : h->keys()) {
93+
auto name = k.name();
12494

125-
while (::codes_bufr_keys_iterator_next(itCtx.get())) {
126-
const char* name = ::codes_bufr_keys_iterator_get_name(itCtx.get());
127-
128-
if (std::strcmp(name, "subsetNumber") == 0) {
95+
if (name == "subsetNumber") {
12996
continue;
13097
}
13198

132-
size_t klen = 0;
133-
13499
/* get key size to see if it is an array */
135-
ASSERT(::codes_get_size(h.get(), name, &klen) == 0);
136-
if (klen != 1) {
100+
if (h->size(name) != 1) {
137101
continue;
138102
}
139103

140-
decodeKey(h.get(), nullptr, name, gather, options);
104+
switch (options.valueRepresentation) {
105+
case eckit::message::ValueRepresentation::String: {
106+
gather.setValue(name, k.getString());
107+
break;
108+
}
109+
case eckit::message::ValueRepresentation::Native: {
110+
std::visit(
111+
[&](auto&& v) {
112+
using Type = std::decay_t<decltype(v)>;
113+
if constexpr (std::is_same_v<Type, std::string> || std::is_arithmetic_v<Type>) {
114+
gather.setValue(name, std::forward<decltype(v)>(v));
115+
}
116+
},
117+
k.get());
118+
break;
119+
}
120+
}
141121
}
142122
}
143123

@@ -152,28 +132,6 @@ eckit::Buffer BUFRDecoder::decode(const eckit::message::Message& msg) const {
152132
return buf;
153133
}
154134

155-
std::string BUFRDecoder::getString(codes_handle* h, codes_keys_iterator*, const char* name) {
156-
char val[1024];
157-
size_t len = sizeof(val);
158-
ASSERT(::codes_get_string(h, name, val, &len) == 0);
159-
return {val, len};
160-
}
161-
162-
long BUFRDecoder::getLong(codes_handle* h, codes_keys_iterator*, const char* name) {
163-
long val;
164-
ASSERT(::codes_get_long(h, name, &val) == 0);
165-
return val;
166-
}
167-
168-
double BUFRDecoder::getDouble(codes_handle* h, codes_keys_iterator*, const char* name) {
169-
double val;
170-
ASSERT(::codes_get_double(h, name, &val) == 0);
171-
return val;
172-
}
173-
174-
bool BUFRDecoder::getBytes(codes_handle* h, codes_keys_iterator*, const char* name, unsigned char* vals, size_t* len) {
175-
return ::codes_get_bytes(h, name, vals, len) == 0;
176-
}
177135

178136
//----------------------------------------------------------------------------------------------------------------------
179137

src/metkit/codes/BUFRDecoder.h

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313

1414
#pragma once
1515

16-
#include "metkit/codes/CodesDecoder.h"
16+
#include "eckit/message/Decoder.h"
17+
#include "eckit/message/Message.h"
1718

1819
#include "eckit/io/Buffer.h"
1920

@@ -23,7 +24,7 @@ namespace codes {
2324

2425
//----------------------------------------------------------------------------------------------------------------------
2526

26-
class BUFRDecoder : public metkit::codes::CodesDecoder<BUFRDecoder> {
27+
class BUFRDecoder : public eckit::message::MessageDecoder {
2728

2829
public: // methods
2930

@@ -38,13 +39,6 @@ class BUFRDecoder : public metkit::codes::CodesDecoder<BUFRDecoder> {
3839
const eckit::message::GetMetadataOptions&) const override;
3940

4041
eckit::Buffer decode(const eckit::message::Message& msg) const override;
41-
42-
public: // methods for decoding the metadata
43-
44-
static std::string getString(codes_handle* h, codes_keys_iterator* it, const char* name);
45-
static long getLong(codes_handle* h, codes_keys_iterator* it, const char* name);
46-
static double getDouble(codes_handle* h, codes_keys_iterator* it, const char* name);
47-
static bool getBytes(codes_handle* h, codes_keys_iterator* it, const char* name, unsigned char* vals, size_t* len);
4842
};
4943

5044
//----------------------------------------------------------------------------------------------------------------------

src/metkit/codes/CodesDecoder.h

Lines changed: 0 additions & 106 deletions
This file was deleted.

0 commit comments

Comments
 (0)