C++ Migration: Unsigned accessor pack / unpack

This commit is contained in:
Eugen Betke 2024-02-26 23:37:34 +00:00
parent 534b59158b
commit 6f5e3c1ddf
10 changed files with 89 additions and 56 deletions

View File

@ -55,7 +55,7 @@ public:
std::vector<double> unpackSubArray(std::size_t start) const;
private:
AccessorDataPtr data_{};
AccessorDataPtr data_ = nullptr;
AccessorName name_;
AccessorNameSpace nameSpace_;
std::vector<AccessorName> allNames_{};
@ -116,4 +116,4 @@ std::vector<T> Accessor::unpackElementSet(std::vector<std::size_t> const& indexA
return data_->unpackElementSet(indexArray, valArray) ? valArray : std::vector<T>{};
}
}
} // namespace eccodes::accessor

View File

@ -10,6 +10,10 @@ namespace eccodes::accessor {
AccessorData::AccessorData(AccessorInitData const& initData)
{
buffer_ = initData.buffer;
length_ = initData.length;
offset_ = initData.offset;
flags_ = initData.flags;
// TO DO - FULL INIT()
}

View File

@ -1,14 +1,14 @@
#pragma once
#include "AccessorDefs.h"
#include "AccessorData/AccessorInitData.h"
#include "AccessorBuffer.h"
#include "AccessorTraits.h"
#include "GribCpp/GribType.h"
#include "GribCpp/GribStatus.h"
#include "GribStub/GribVirtualValueStub.h"
#include "GribStub/GribActionStub.h"
#include "GribStub/GribSectionStub.h"
#include "../AccessorDefs.h"
#include "AccessorInitData.h"
#include "../AccessorBuffer.h"
#include "../AccessorTraits.h"
#include "../GribCpp/GribType.h"
#include "../GribCpp/GribStatus.h"
#include "../GribStub/GribVirtualValueStub.h"
#include "../GribStub/GribActionStub.h"
#include "../GribStub/GribSectionStub.h"
#include <string>
#include <memory>
#include <vector>
@ -112,12 +112,12 @@ GribStatus AccessorData::unpack(T &value) const
std::vector<T> values;
unpack(values);
if(values.size() == 1) {
if (values.size() == 1) {
value = values[0];
return GribStatus::SUCCESS;
return GribStatus::SUCCESS;
}
return GribStatus::COUNT_MISMATCH;
}
}
} // namespace eccodes::accessor

View File

@ -1,12 +1,16 @@
#include "AccessorInitData.h"
#include "GribCpp/GribType.h"
#include "grib_api_internal.h"
#include <iostream>
namespace eccodes::accessor {
AccessorInitData makeInitData(grib_section* section, long len, grib_arguments* args)
AccessorInitData makeInitData(grib_section* section, long len, grib_arguments* args, grib_accessor* a, grib_action* act, grib_section* s)
{
AccessorInitData initData{len};
initData.offset = a->offset;
initData.flags = a->flags;
initData.buffer = AccessorDataView((unsigned char*) s->h->buffer->data, s->h->buffer->length);
grib_arguments* next_arg = args;
@ -53,6 +57,19 @@ AccessorInitData makeInitData(grib_section* section, long len, grib_arguments* a
next_arg = next_arg->next;
}
// print arguments
for (auto const& [name, value] : initData.args)
{
if (std::holds_alternative<long>(value))
std::cout << "\t- AccessorInitData: " << name << " = " << std::get<long>(value) << std::endl;
else if (std::holds_alternative<double>(value))
std::cout << "\t- AccessorInitData: " << name << " = " << std::get<double>(value) << std::endl;
else if (std::holds_alternative<std::string>(value))
std::cout << "\t- AccessorInitData: " << name << " = " << std::get<std::string>(value) << std::endl;
else
std::cout << "\t- AccessorInitData: " << name << " = " << "undefined" << std::endl;
}
return initData;
}

View File

@ -5,6 +5,9 @@
#include <vector>
#include <memory>
#include "grib_api_internal.h"
#include "AccessorBuffer.h"
struct grib_section;
struct grib_arguments;
@ -22,8 +25,11 @@ using AccessorInitArguments = std::vector<AccessorInitArgumentEntry>;
struct AccessorInitData{
long length{};
AccessorInitArguments args;
size_t offset{};
unsigned long flags{};
AccessorDataView buffer;
};
AccessorInitData makeInitData(grib_section* section, long len, grib_arguments* args);
AccessorInitData makeInitData(grib_section* section, long len, grib_arguments* args, grib_accessor* a, grib_action* act, grib_section* sect);
} // namespace eccodes::accessor

View File

@ -9,7 +9,7 @@ struct grib_accessor;
namespace eccodes::accessor {
using AccessorEntry = std::pair<eccodes::accessor::AccessorName, eccodes::accessor::AccessorPtr>;
using AccessorEntry = std::pair<AccessorName, AccessorPtr>;
class AccessorStore {
std::vector<AccessorEntry> store_{};

View File

@ -1,13 +1,13 @@
#pragma once
#include "grib_api_internal.h"
#include <type_traits>
#include <string>
#include <vector>
// Trait definitions for accessor templates
struct grib_expression;
namespace eccodes::accessor {
using StringArray = std::vector<std::string>;
@ -38,4 +38,4 @@ struct isAllowedUnpackType : std::integral_constant<bool,
isAllowedBufferType<T>::value
> {};
}
} // namespace eccodes::accessor

View File

@ -7,14 +7,12 @@ namespace eccodes::accessor {
unsigned long gribDecodeUnsignedLong(const AccessorDataPointer input, long& bitPos, long numBits)
{
assert(false); // TODO
return 0;
return grib_decode_unsigned_long(input, &bitPos, numBits);
}
unsigned long gribDecodeUnsignedLong(const AccessorDataBuffer& input, long& bitPos, long numBits)
{
assert(false); // TODO
return 0;
return grib_decode_unsigned_long(input.data(), &bitPos, numBits);
}
GribStatus gribEncodeUnsignedLong(AccessorDataPointer p, unsigned long val, long& bitPos, long numBits)

View File

@ -162,6 +162,14 @@ int grib_pack_long(grib_accessor* a, const long* v, size_t* len)
{
grib_accessor_class* c = a->cclass;
/*grib_context_log(a->context, GRIB_LOG_DEBUG, "(%s)%s is packing (long) %d",(a->parent->owner)?(a->parent->owner->name):"root", a->name ,v?(*v):0); */
auto accessorPtr = eccodes::accessor::get(eccodes::accessor::AccessorName(a->name));
if (accessorPtr) {
const std::vector<long> values{*v};
if (accessorPtr->pack(values) == eccodes::accessor::GribStatus::SUCCESS)
return GRIB_SUCCESS;
}
while (c) {
if (c->pack_long) {
return c->pack_long(a, v, len);
@ -416,15 +424,15 @@ int grib_unpack_long(grib_accessor* a, long* v, size_t* len)
/*grib_context_log(a->context, GRIB_LOG_DEBUG, "(%s)%s is unpacking (long)",(a->parent->owner)?(a->parent->owner->name):"root", a->name ); */
auto accessorPtr = eccodes::accessor::get(eccodes::accessor::AccessorName(a->name));
if (accessorPtr) {
*v = accessorPtr->unpack<long>();
*len = 1;
return GRIB_SUCCESS;
}
while (c) {
if (c->unpack_long) {
int ret = c->unpack_long(a, v, len);
if (accessorPtr) {
long cxx_value = accessorPtr->unpack<long>();
std::cout << "*v != cxx_value: " << *v << " " << cxx_value << std::endl;
assert(*v == cxx_value);
}
return ret;
}
c = c->super ? *(c->super) : NULL;

View File

@ -18,8 +18,8 @@
#include "grib_accessor_class.h"
// C++ Support
#include "cpp/eccodes/accessor/AccessorFactory.h"
#include "cpp/eccodes/accessor/AccessorStore.h"
#include "AccessorFactory.h"
#include "AccessorStore.h"
#include <iostream>
#include <cassert>
@ -141,24 +141,6 @@ grib_accessor* grib_accessor_factory(grib_section* p, grib_action* creator,
grib_accessor* a = NULL;
size_t size = 0;
// C++ Accessors
#ifdef USE_CPP_ACCESSORS
using namespace eccodes::accessor;
auto accessorType = AccessorType(creator->op);
if (strcmp(creator->op, "unsigned") == 0) {
std::cerr << "unsigned accessor" << std::endl;
}
if (auto& factory = AccessorFactory::instance(); factory.has(accessorType))
{
auto accessorName = AccessorName(creator->name);
auto accessorNameSpace = AccessorNameSpace(creator->name_space ? creator->name_space : "");
auto initData = makeInitData(p, len, params);
auto accessorPtr = factory.build(accessorType, accessorName, accessorNameSpace, initData);
Assert(accessorPtr);
}
#endif // USE_CPP_ACCESSORS
#ifdef ACCESSOR_FACTORY_USE_TRIE
c = get_class(p->h->context, creator->op);
#else
@ -166,14 +148,8 @@ grib_accessor* grib_accessor_factory(grib_section* p, grib_action* creator,
c = *((grib_accessor_classes_hash(creator->op, strlen(creator->op)))->cclass);
#endif
a = (grib_accessor*)grib_context_malloc_clear(p->h->context, c->size);
// C++ - we'll keep a copy of the grib_accessor pointer for any accessors not yet implemented
#ifdef USE_CPP_ACCESSORS
add_grib_accessor(AccessorName(creator->name), a);
#endif // USE_CPP_ACCESSORS
a->name = creator->name;
a->name_space = creator->name_space;
@ -247,6 +223,30 @@ grib_accessor* grib_accessor_factory(grib_section* p, grib_action* creator,
a->name, creator->op, a->offset, len, p->block);
}
// C++ Accessors
#ifdef USE_CPP_ACCESSORS
using namespace eccodes::accessor;
auto accessorType = AccessorType(creator->op);
if (auto& factory = AccessorFactory::instance(); factory.has(accessorType))
{
//std::cout << "AccessorFactory has " << creator->op << std::endl;
//std::cout << "\t - Offset: " << a->offset << " Length: " << a->length << std::endl;
long section_count = p->h->sections_count;
auto accessorName = AccessorName(creator->name);
auto accessorNameSpace = AccessorNameSpace(creator->name_space ? creator->name_space : "");
auto initData = makeInitData(p, len, params, a, creator, p);
auto accessorPtr = factory.build(accessorType, accessorName, accessorNameSpace, initData);
Assert(accessorPtr);
}
// C++ - we'll keep a copy of the grib_accessor pointer for any accessors not yet implemented
add_grib_accessor(AccessorName(creator->name), a);
#endif // USE_CPP_ACCESSORS
return a;
}