Skip to content

Commit 4bf0ef7

Browse files
committed
CodesHandle::getBytes: use length instead of size to determine array size
1 parent c381622 commit 4bf0ef7

File tree

4 files changed

+53
-18
lines changed

4 files changed

+53
-18
lines changed

src/metkit/codes/BUFRDecoder.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,19 @@ void BUFRDecoder::getMetadata(const eckit::message::Message& msg, eckit::message
113113
if constexpr (std::is_same_v<Type, std::string> || std::is_arithmetic_v<Type>) {
114114
gather.setValue(name, std::forward<decltype(v)>(v));
115115
}
116+
if constexpr (std::is_same_v<Type, std::vector<uint8_t>>) {
117+
static const char hex_digits[] = "0123456789abcdef";
118+
std::string out;
119+
out.resize(v.size() * 2);
120+
121+
for (size_t i = 0; i < v.size(); i++) {
122+
uint8_t b = v[i];
123+
out[2 * i] = hex_digits[b >> 4];
124+
out[2 * i + 1] = hex_digits[b & 0x0F];
125+
}
126+
127+
gather.setValue(name, out);
128+
}
116129
},
117130
k.get());
118131
break;

src/metkit/codes/GRIBDecoder.cc

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@
1616
#include "metkit/codes/GRIBDecoder.h"
1717
#include "metkit/codes/api/CodesAPI.h"
1818

19+
#include "eccodes.h"
20+
1921
#include <algorithm>
2022
#include <iostream>
2123

22-
#include "eccodes.h"
23-
2424

2525
namespace metkit {
2626
namespace codes {
@@ -60,21 +60,27 @@ void GRIBDecoder::getMetadata(const eckit::message::Message& msg, eckit::message
6060
break;
6161
}
6262
case eckit::message::ValueRepresentation::Native: {
63-
// https://jira.ecmwf.int/browse/ECC-2166
64-
if (name == "uuidOfHGrid") {
65-
// uuidOfHGrid returns size 1 although it contains 16 bytes
66-
gather.setValue(name, k.getString());
67-
}
68-
else {
69-
std::visit(
70-
[&](auto&& v) {
71-
using Type = std::decay_t<decltype(v)>;
72-
if constexpr (std::is_same_v<Type, std::string> || std::is_arithmetic_v<Type>) {
73-
gather.setValue(name, std::forward<decltype(v)>(v));
63+
std::visit(
64+
[&](auto&& v) {
65+
using Type = std::decay_t<decltype(v)>;
66+
if constexpr (std::is_same_v<Type, std::string> || std::is_arithmetic_v<Type>) {
67+
gather.setValue(name, std::forward<decltype(v)>(v));
68+
}
69+
if constexpr (std::is_same_v<Type, std::vector<uint8_t>>) {
70+
static const char hex_digits[] = "0123456789abcdef";
71+
std::string out;
72+
out.resize(v.size() * 2);
73+
74+
for (size_t i = 0; i < v.size(); i++) {
75+
uint8_t b = v[i];
76+
out[2 * i] = hex_digits[b >> 4];
77+
out[2 * i + 1] = hex_digits[b & 0x0F];
7478
}
75-
},
76-
k.get());
77-
}
79+
80+
gather.setValue(name, out);
81+
}
82+
},
83+
k.get());
7884
break;
7985
}
8086
}

src/metkit/codes/api/CodesAPI.cc

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "eccodes.h"
1717

18+
1819
namespace std {
1920
template <>
2021
struct default_delete<codes_handle> {
@@ -85,6 +86,7 @@ class OwningCodesHandle : public CodesHandle {
8586
void forceSet(const std::string& key, Span<const double> value) override;
8687
void forceSet(const std::string& key, Span<const float> value) override;
8788
size_t size(const std::string& key) const override;
89+
size_t length(const std::string& key) const override;
8890
CodesValue get(const std::string& key) const override;
8991
NativeType type(const std::string& key) const override;
9092
long getLong(const std::string& key) const override;
@@ -214,6 +216,12 @@ size_t OwningCodesHandle::size(const std::string& key) const {
214216
return size;
215217
}
216218

219+
size_t OwningCodesHandle::length(const std::string& key) const {
220+
size_t length;
221+
throwOnError(codes_get_length(raw(), key.c_str(), &length), Here(), "CodesHandle::length(string)", key);
222+
return length;
223+
}
224+
217225
/// Get the value of the key
218226
CodesValue OwningCodesHandle::get(const std::string& key) const {
219227
NativeType ktype = type(key);
@@ -345,7 +353,7 @@ std::vector<std::string> OwningCodesHandle::getStringArray(const std::string& ke
345353

346354
std::vector<uint8_t> OwningCodesHandle::getBytes(const std::string& key) const {
347355
std::vector<uint8_t> ret;
348-
std::size_t ksize = size(key);
356+
std::size_t ksize = length(key) / 2;
349357
ret.resize(ksize);
350358
throwOnError(codes_get_bytes(raw(), key.c_str(), ret.data(), &ksize), Here(), "CodesHandle::getBytes(string)", key);
351359
ret.resize(ksize);
@@ -489,7 +497,7 @@ class ConcreteKeyIterator : public KeyIterator {
489497
std::vector<uint8_t> getBytes() const override {
490498
std::vector<uint8_t> ret;
491499
std::string key = name();
492-
std::size_t size = refHandle_.get().size(key);
500+
std::size_t size = refHandle_.get().length(key) / 2;
493501
ret.resize(size);
494502
throwOnError(codes_keys_iterator_get_bytes(it_.get(), ret.data(), &size), Here(), "KeyIterator::getBytes()");
495503
ret.resize(size);

src/metkit/codes/api/CodesAPI.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,14 @@ class CodesHandle {
203203
/// @return For given scalars 1 is returned. For given arrays the size of the array is returned..
204204
virtual size_t size(const std::string& key) const = 0;
205205

206+
/// Returns the number of chars/bytes contained for a given key
207+
// of type string/byte array.
208+
///
209+
/// Can be used to determine if a field is storing a scalar or an array.
210+
/// @param key Name of the field that is supposed to be inspected.
211+
/// @return Number of chars/bytes of contained string/byte array
212+
virtual size_t length(const std::string& key) const = 0;
213+
206214
/// Get the value of the key.
207215
///
208216
/// High-level functionality:

0 commit comments

Comments
 (0)