Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/metkit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,6 @@ if ( HAVE_GRIB )
codes/UserDataContent.h
codes/DataContent.cc
codes/DataContent.h
codes/MallocCodesContent.cc
codes/MallocCodesContent.h
codes/CodesSplitter.cc
codes/CodesSplitter.h
codes/GribAccessor.cc
Expand Down
25 changes: 23 additions & 2 deletions src/metkit/codes/BUFRDecoder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,15 @@ void BUFRDecoder::getMetadata(const eckit::message::Message& msg, eckit::message
// https://confluence.ecmwf.int/display/ECC/bufr_keys_iterator
h->set("unpack", 1);

for (auto& k : h->keys()) {
for (const auto& k : h->keys()) {
auto name = k.name();

if (name == "subsetNumber") {
continue;
}

/* get key size to see if it is an array */
// Get key size to see if it is an array
// Only continue for scalar values
if (h->size(name) != 1) {
continue;
}
Expand All @@ -113,6 +114,26 @@ void BUFRDecoder::getMetadata(const eckit::message::Message& msg, eckit::message
if constexpr (std::is_same_v<Type, std::string> || std::is_arithmetic_v<Type>) {
gather.setValue(name, std::forward<decltype(v)>(v));
}
else if constexpr (std::is_same_v<Type, std::vector<uint8_t>>) {
static const char hex_digits[] = "0123456789abcdef";
std::string out;
out.resize(v.size() * 2);

for (size_t i = 0; i < v.size(); i++) {
uint8_t b = v[i];
out[2 * i] = hex_digits[b >> 4];
out[2 * i + 1] = hex_digits[b & 0x0F];
}

gather.setValue(name, out);
}
else {
// Unhandled types are all array types - the prior call checking `size != 1` only allows for
// scalars.
throw eckit::Exception(
std::string("Unexpected type when accessing BURF message metadata ") + typeid(v).name(),
Here());
}
},
k.get());
break;
Expand Down
27 changes: 3 additions & 24 deletions src/metkit/codes/BufrContent.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,8 @@
* does it submit to any jurisdiction.
*/

/// @author Baudouin Raoult
/// @author Emanuele Danovaro
/// @date Mar 2022

#include "metkit/codes/BufrContent.h"

#include "metkit/codes/GribHandle.h"

#include "eccodes.h"

namespace metkit {
Expand All @@ -24,29 +18,14 @@ namespace codes {

//----------------------------------------------------------------------------------------------------------------------

BufrContent::BufrContent(codes_handle* handle, bool delete_handle) : CodesContent(handle, delete_handle) {}

BufrContent::BufrContent(const codes_handle* handle) : BufrContent(const_cast<codes_handle*>(handle), false) {}

BufrContent::~BufrContent() {}

BufrContent::BufrContent(std::unique_ptr<CodesHandle> handle) : CodesContent(std::move(handle)) {}

//----------------------------------------------------------------------------------------------------------------------

void BufrContent::transform(const eckit::OrderedStringDict& dict) {

std::vector<codes_values> values;

for (auto& kv : dict) {
codes_values v;
v.name = kv.first.c_str();
v.long_value = std::stol(kv.second);
v.type = GRIB_TYPE_LONG;

values.push_back(v);
for (const auto& [key, value] : dict) {
handle_->set(key, std::stol(value));
}

CODES_CALL(codes_set_values(handle_, values.data(), values.size()));
}


Expand Down
5 changes: 2 additions & 3 deletions src/metkit/codes/BufrContent.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,9 @@ namespace codes {
class BufrContent : public CodesContent {
public:

BufrContent(codes_handle* handle, bool delete_handle);
explicit BufrContent(const codes_handle* handle);
BufrContent(std::unique_ptr<CodesHandle> handle);

~BufrContent();
virtual ~BufrContent() = default;

protected:

Expand Down
116 changes: 22 additions & 94 deletions src/metkit/codes/CodesContent.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@
* does it submit to any jurisdiction.
*/

/// @author Baudouin Raoult
/// @date Jun 2020

#include "metkit/codes/CodesContent.h"

#include "eccodes.h"
Expand All @@ -19,46 +16,28 @@
#include "eckit/io/DataHandle.h"
#include "eckit/io/MemoryHandle.h"

#include "eckit/memory/Zero.h"

#include "metkit/codes/GribHandle.h"

namespace metkit {
namespace codes {

//----------------------------------------------------------------------------------------------------------------------

CodesContent::CodesContent(codes_handle* handle, bool delete_handle) : handle_(handle), delete_handle_(delete_handle) {
ASSERT(handle_);
}

CodesContent::CodesContent(const codes_handle* handle) : CodesContent(const_cast<codes_handle*>(handle), false) {}


CodesContent::~CodesContent() {
if (delete_handle_) {
codes_handle_delete(handle_);
}
}
CodesContent::CodesContent(std::unique_ptr<CodesHandle> handle) : handle_(std::move(handle)) {}


//----------------------------------------------------------------------------------------------------------------------

size_t CodesContent::length() const {
size_t size;
const void* data;
CODES_CALL(codes_get_message(handle_, &data, &size));
return size;
return handle_->messageSize();
}


//----------------------------------------------------------------------------------------------------------------------

void CodesContent::write(eckit::DataHandle& handle) const {
size_t size;
const void* data;
CODES_CALL(codes_get_message(handle_, &data, &size));
if (handle.write(data, size) != size) {
auto data = handle_->messageData();
if (handle.write(data.data(), data.size()) != data.size()) {
std::ostringstream oss;
oss << "Write error to data handle " << handle;
throw eckit::WriteError(oss.str(), Here());
Expand All @@ -69,10 +48,8 @@ void CodesContent::write(eckit::DataHandle& handle) const {
//----------------------------------------------------------------------------------------------------------------------

eckit::DataHandle* CodesContent::readHandle() const {
size_t size;
const void* data;
CODES_CALL(codes_get_message(handle_, &data, &size));
return new eckit::MemoryHandle(data, size);
auto data = handle_->messageData();
return new eckit::MemoryHandle(data.data(), data.size());
}


Expand All @@ -86,128 +63,79 @@ void CodesContent::print(std::ostream& s) const {
//----------------------------------------------------------------------------------------------------------------------

std::string CodesContent::getString(const std::string& key) const {
char values[10240];
size_t len = sizeof(values);

values[0] = 0;

CODES_CALL(codes_get_string(handle_, key.c_str(), values, &len));
// ASSERT(err)

return values;
return handle_->getString(key);
}

//----------------------------------------------------------------------------------------------------------------------

long CodesContent::getLong(const std::string& key) const {
long v = 0;
CODES_CALL(codes_get_long(handle_, key.c_str(), &v));
return v;
return handle_->getLong(key);
}


//----------------------------------------------------------------------------------------------------------------------

double CodesContent::getDouble(const std::string& key) const {
double v = 0;
CODES_CALL(codes_get_double(handle_, key.c_str(), &v));
return v;
return handle_->getDouble(key);
}


//----------------------------------------------------------------------------------------------------------------------

void CodesContent::getDoubleArray(const std::string& key, std::vector<double>& values) const {
size_t size = 0;
CODES_CALL(codes_get_size(handle_, key.c_str(), &size));

size_t count = size;
values.resize(count);
CODES_CALL(codes_get_double_array(handle_, key.c_str(), &values[0], &count));
ASSERT(count == size);
values = handle_->getDoubleArray(key);
}

//----------------------------------------------------------------------------------------------------------------------

void CodesContent::getFloatArray(const std::string& key, std::vector<float>& values) const {
size_t size = 0;
CODES_CALL(codes_get_size(handle_, key.c_str(), &size));

size_t count = size;
values.resize(count);
CODES_CALL(codes_get_float_array(handle_, key.c_str(), &values[0], &count));
ASSERT(count == size);
values = handle_->getFloatArray(key);
}


//----------------------------------------------------------------------------------------------------------------------

size_t CodesContent::getSize(const std::string& key) const {
size_t size = 0;
CODES_CALL(codes_get_size(handle_, key.c_str(), &size));
return size;
return handle_->size(key);
}


//----------------------------------------------------------------------------------------------------------------------

void CodesContent::getDoubleArray(const std::string& key, double* data, size_t len) const {
size_t count = len;
CODES_CALL(codes_get_double_array(handle_, key.c_str(), data, &count));
ASSERT(count == len);
auto arr = handle_->getDoubleArray(key);
ASSERT(len == arr.size());
std::copy(arr.begin(), arr.end(), data);
}

//----------------------------------------------------------------------------------------------------------------------

void CodesContent::getFloatArray(const std::string& key, float* data, size_t len) const {
size_t count = len;
CODES_CALL(codes_get_float_array(handle_, key.c_str(), data, &count));
ASSERT(count == len);
auto arr = handle_->getFloatArray(key);
ASSERT(len == arr.size());
std::copy(arr.begin(), arr.end(), data);
}


//----------------------------------------------------------------------------------------------------------------------

void CodesContent::transform(const eckit::OrderedStringDict& dict) {

std::vector<codes_values> values;
values.reserve(dict.size());

for (auto& kv : dict) {
codes_values v;
v.name = kv.first.c_str();
v.string_value = kv.second.c_str();
v.type = GRIB_TYPE_STRING;

values.push_back(v);
for (auto& [key, value] : dict) {
handle_->set(key, value);
}

CODES_CALL(codes_set_values(handle_, values.data(), values.size()));
}

//----------------------------------------------------------------------------------------------------------------------

eckit::Offset CodesContent::offset() const {
long pos;
CODES_CALL(codes_get_long(handle_, "offset", &pos));
return pos;
}


//----------------------------------------------------------------------------------------------------------------------

const codes_handle* CodesContent::codesHandle() const {
return handle_;
return handle_->getLong("offset");
}


//----------------------------------------------------------------------------------------------------------------------

const void* CodesContent::data() const {
size_t size;
const void* data;
CODES_CALL(codes_get_message(handle_, &data, &size));
return data;
return handle_->messageData().data();
}


Expand Down
15 changes: 5 additions & 10 deletions src/metkit/codes/CodesContent.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,35 +13,31 @@

#pragma once

#include "eckit/message/MessageContent.h"
#include "metkit/codes/api/CodesAPI.h"

typedef struct grib_handle codes_handle;
#include "eckit/message/MessageContent.h"

namespace metkit {
namespace codes {


//----------------------------------------------------------------------------------------------------------------------

class CodesContent : public eckit::message::MessageContent {
public:

CodesContent(codes_handle* handle, bool delete_handle);
explicit CodesContent(const codes_handle* handle);
CodesContent(std::unique_ptr<CodesHandle> handle);

~CodesContent();
virtual ~CodesContent() = default;

protected:

codes_handle* handle_;
std::unique_ptr<CodesHandle> handle_;

using eckit::message::MessageContent::transform;
void transform(const eckit::OrderedStringDict&) override;

private:

bool delete_handle_;

size_t length() const override;
void write(eckit::DataHandle& handle) const override;
eckit::DataHandle* readHandle() const override;
Expand All @@ -56,7 +52,6 @@ class CodesContent : public eckit::message::MessageContent {
void getFloatArray(const std::string& key, float* data, size_t lenExpected) const override;

eckit::Offset offset() const override;
const codes_handle* codesHandle() const;
const void* data() const override;
};

Expand Down
Loading
Loading