2013-03-25 12:04:10 +00:00
|
|
|
/*
|
2019-04-15 13:44:45 +00:00
|
|
|
* Copyright 2005-2019 ECMWF.
|
2013-03-25 12:04:10 +00:00
|
|
|
*
|
|
|
|
* This software is licensed under the terms of the Apache Licence Version 2.0
|
|
|
|
* which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
|
|
|
|
*
|
|
|
|
* In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
|
|
|
|
* virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
|
|
|
|
*/
|
|
|
|
|
2019-05-13 10:57:31 +00:00
|
|
|
|
2013-03-25 12:04:10 +00:00
|
|
|
#include "grib_api_internal.h"
|
|
|
|
#include "grib_accessor_classes_hash.c"
|
|
|
|
/* grib level */
|
|
|
|
|
|
|
|
|
2016-08-31 08:59:21 +00:00
|
|
|
/* This file is generated by ./make_class.pl */
|
2013-03-25 12:04:10 +00:00
|
|
|
#include "grib_accessor_class.h"
|
|
|
|
|
|
|
|
#if GRIB_PTHREADS
|
2020-01-22 13:10:59 +00:00
|
|
|
static pthread_once_t once = PTHREAD_ONCE_INIT;
|
2013-03-25 12:04:10 +00:00
|
|
|
static pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
static void init()
|
|
|
|
{
|
2013-03-25 12:04:10 +00:00
|
|
|
pthread_mutexattr_t attr;
|
|
|
|
pthread_mutexattr_init(&attr);
|
2020-01-22 13:10:59 +00:00
|
|
|
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
|
|
|
pthread_mutex_init(&mutex1, &attr);
|
2013-03-25 12:04:10 +00:00
|
|
|
pthread_mutexattr_destroy(&attr);
|
|
|
|
}
|
2015-12-30 14:39:02 +00:00
|
|
|
#elif GRIB_OMP_THREADS
|
|
|
|
static int once = 0;
|
|
|
|
static omp_nest_lock_t mutex1;
|
|
|
|
|
|
|
|
static void init()
|
|
|
|
{
|
|
|
|
GRIB_OMP_CRITICAL(lock_grib_accessor_class_c)
|
|
|
|
{
|
2020-01-22 13:10:59 +00:00
|
|
|
if (once == 0) {
|
2015-12-30 14:39:02 +00:00
|
|
|
omp_init_nest_lock(&mutex1);
|
|
|
|
once = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
struct table_entry
|
|
|
|
{
|
2020-01-22 13:10:59 +00:00
|
|
|
char* type;
|
|
|
|
grib_accessor_class** cclass;
|
2013-03-25 12:04:10 +00:00
|
|
|
};
|
|
|
|
|
2018-05-18 18:06:50 +00:00
|
|
|
#ifdef ACCESSOR_FACTORY_USE_TRIE
|
2017-06-07 12:53:01 +00:00
|
|
|
/* Note: A fast cut-down version of strcmp which does NOT return -1 */
|
|
|
|
/* 0 means input strings are equal and 1 means not equal */
|
2020-01-22 13:10:59 +00:00
|
|
|
static GRIB_INLINE int grib_inline_strcmp(const char* a, const char* b)
|
2016-08-31 08:59:21 +00:00
|
|
|
{
|
2020-01-22 13:10:59 +00:00
|
|
|
if (*a != *b)
|
|
|
|
return 1;
|
|
|
|
while ((*a != 0 && *b != 0) && *(a) == *(b)) {
|
|
|
|
a++;
|
|
|
|
b++;
|
|
|
|
}
|
|
|
|
return (*a == 0 && *b == 0) ? 0 : 1;
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
static struct table_entry table[] = {
|
2016-08-31 08:59:21 +00:00
|
|
|
/* This file is generated by ./make_class.pl */
|
2013-03-25 12:04:10 +00:00
|
|
|
#include "grib_accessor_factory.h"
|
|
|
|
};
|
2018-05-18 18:06:50 +00:00
|
|
|
#endif
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
#define NUMBER(x) (sizeof(x) / sizeof(x[0]))
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
grib_section* grib_create_root_section(const grib_context* context, grib_handle* h)
|
2013-03-25 12:04:10 +00:00
|
|
|
{
|
2020-01-22 13:10:59 +00:00
|
|
|
char* fpath = 0;
|
|
|
|
grib_section* s = (grib_section*)grib_context_malloc_clear(context, sizeof(grib_section));
|
2013-06-19 12:13:45 +00:00
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
GRIB_MUTEX_INIT_ONCE(&once, &init);
|
2013-06-19 12:13:45 +00:00
|
|
|
GRIB_MUTEX_LOCK(&mutex1);
|
2020-01-22 13:10:59 +00:00
|
|
|
if (h->context->grib_reader == NULL) {
|
|
|
|
if ((fpath = grib_context_full_defs_path(h->context, "boot.def")) == NULL) {
|
|
|
|
grib_context_log(h->context, GRIB_LOG_FATAL,
|
|
|
|
"Unable to find boot.def. Context path=%s\n"
|
|
|
|
"\nPossible causes:\n"
|
|
|
|
"- The software is not correctly installed\n"
|
|
|
|
"- The environment variable ECCODES_DEFINITION_PATH is defined but incorrect\n",
|
|
|
|
context->grib_definition_files_path);
|
2013-06-19 12:13:45 +00:00
|
|
|
}
|
2020-01-22 13:10:59 +00:00
|
|
|
grib_parse_file(h->context, fpath);
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
2013-06-19 12:13:45 +00:00
|
|
|
GRIB_MUTEX_UNLOCK(&mutex1);
|
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
s->h = h;
|
2013-06-19 12:13:45 +00:00
|
|
|
s->aclength = NULL;
|
2016-02-23 11:53:47 +00:00
|
|
|
s->owner = NULL;
|
2013-06-19 12:13:45 +00:00
|
|
|
s->block = (grib_block_of_accessors*)
|
2020-01-22 13:10:59 +00:00
|
|
|
grib_context_malloc_clear(context, sizeof(grib_block_of_accessors));
|
2013-06-19 12:13:45 +00:00
|
|
|
grib_context_log(context, GRIB_LOG_DEBUG, "Creating root section");
|
|
|
|
return s;
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
|
2018-01-23 14:49:41 +00:00
|
|
|
/* Only used if ACCESSOR_FACTORY_USE_TRIE */
|
2018-05-18 18:06:50 +00:00
|
|
|
#ifdef ACCESSOR_FACTORY_USE_TRIE
|
2020-01-22 13:10:59 +00:00
|
|
|
static GRIB_INLINE grib_accessor_class* get_class(grib_context* c, char* type)
|
2016-02-23 11:53:47 +00:00
|
|
|
{
|
2013-06-19 12:13:45 +00:00
|
|
|
int i;
|
2020-01-22 13:10:59 +00:00
|
|
|
int table_count = 0;
|
|
|
|
grib_accessor_class** the_class = NULL;
|
2013-06-19 12:13:45 +00:00
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
if ((the_class = (grib_accessor_class**)grib_trie_get(c->classes, type)) != NULL)
|
2014-10-02 15:50:49 +00:00
|
|
|
return *(the_class);
|
2013-06-19 12:13:45 +00:00
|
|
|
|
2017-06-28 12:13:31 +00:00
|
|
|
table_count = NUMBER(table);
|
2020-01-22 13:10:59 +00:00
|
|
|
for (i = 0; i < table_count; i++) {
|
|
|
|
if (grib_inline_strcmp(type, table[i].type) == 0) {
|
|
|
|
grib_trie_insert(c->classes, type, table[i].cclass);
|
2013-06-19 12:13:45 +00:00
|
|
|
return *(table[i].cclass);
|
|
|
|
}
|
|
|
|
}
|
2016-06-13 16:49:12 +00:00
|
|
|
grib_context_log(c, GRIB_LOG_ERROR, "ecCodes Version: %s\nDefinition files path: %s\n",
|
2020-01-22 13:10:59 +00:00
|
|
|
ECCODES_VERSION_STR, c->grib_definition_files_path);
|
|
|
|
grib_context_log(c, GRIB_LOG_FATAL, "unable to create class %s", type);
|
2013-06-19 12:13:45 +00:00
|
|
|
return NULL;
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
2018-05-18 18:06:50 +00:00
|
|
|
#endif
|
2013-03-25 12:04:10 +00:00
|
|
|
|
|
|
|
grib_accessor* grib_accessor_factory(grib_section* p, grib_action* creator,
|
2020-01-22 13:10:59 +00:00
|
|
|
const long len, grib_arguments* params)
|
2013-03-25 12:04:10 +00:00
|
|
|
{
|
2020-01-22 13:10:59 +00:00
|
|
|
grib_accessor_class* c = NULL;
|
|
|
|
grib_accessor* a = NULL;
|
|
|
|
size_t size = 0;
|
2013-06-19 12:13:45 +00:00
|
|
|
|
2018-01-23 14:49:41 +00:00
|
|
|
#ifdef ACCESSOR_FACTORY_USE_TRIE
|
2020-01-22 13:10:59 +00:00
|
|
|
c = get_class(p->h->context, creator->op);
|
2018-01-23 14:49:41 +00:00
|
|
|
#else
|
|
|
|
/* Use the hash table built with gperf (See make_accessor_class_hash.ksh) */
|
2020-01-22 13:10:59 +00:00
|
|
|
c = *((grib_accessor_classes_hash(creator->op, strlen(creator->op)))->cclass);
|
2018-01-23 14:49:41 +00:00
|
|
|
#endif
|
2018-01-23 11:49:41 +00:00
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
a = (grib_accessor*)grib_context_malloc_clear(p->h->context, c->size);
|
2013-06-19 12:13:45 +00:00
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
a->name = creator->name;
|
|
|
|
a->name_space = creator->name_space;
|
2013-06-19 12:13:45 +00:00
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
a->all_names[0] = creator->name;
|
|
|
|
a->all_name_spaces[0] = creator->name_space;
|
2013-06-19 12:13:45 +00:00
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
a->creator = creator;
|
|
|
|
a->context = p->h->context;
|
|
|
|
a->h = NULL;
|
|
|
|
a->next = NULL;
|
|
|
|
a->previous = NULL;
|
|
|
|
a->parent = p;
|
|
|
|
a->length = 0;
|
|
|
|
a->offset = 0;
|
|
|
|
a->flags = creator->flags;
|
|
|
|
a->set = creator->set;
|
2013-06-19 12:13:45 +00:00
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
if (p->block->last) {
|
|
|
|
a->offset = grib_get_next_position_offset(p->block->last);
|
2013-06-19 12:13:45 +00:00
|
|
|
#if 0
|
|
|
|
printf("offset: p->block->last %s %s %ld %ld\n",
|
|
|
|
p->block->last->cclass->name,
|
|
|
|
p->block->last->name,(long)p->block->last->offset,(long)p->block->last->length);
|
|
|
|
#endif
|
2020-01-22 13:10:59 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (p->owner) {
|
|
|
|
a->offset = p->owner->offset;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
a->offset = 0;
|
2013-06-19 12:13:45 +00:00
|
|
|
}
|
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
a->cclass = c;
|
2013-06-19 12:13:45 +00:00
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
grib_init_accessor(a, len, params);
|
2013-06-19 12:13:45 +00:00
|
|
|
size = grib_get_next_position_offset(a);
|
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
if (size > p->h->buffer->ulength) {
|
|
|
|
if (!p->h->buffer->growable) {
|
|
|
|
if (!p->h->partial)
|
2013-06-19 12:13:45 +00:00
|
|
|
grib_context_log(p->h->context, GRIB_LOG_ERROR,
|
2020-01-22 13:10:59 +00:00
|
|
|
"Creating (%s)%s of %s at offset %d-%d over message boundary (%d)",
|
|
|
|
p->owner ? p->owner->name : "", a->name,
|
|
|
|
creator->op, a->offset,
|
|
|
|
a->offset + a->length,
|
|
|
|
p->h->buffer->ulength);
|
2013-06-19 12:13:45 +00:00
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
grib_accessor_delete(p->h->context, a);
|
2013-06-19 12:13:45 +00:00
|
|
|
return NULL;
|
2020-01-22 13:10:59 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
grib_context_log(p->h->context, GRIB_LOG_DEBUG,
|
|
|
|
"CREATE: name=%s class=%s offset=%ld length=%ld action=",
|
|
|
|
a->name, a->cclass->name, a->offset, a->length);
|
2013-06-19 12:13:45 +00:00
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
grib_grow_buffer(p->h->context, p->h->buffer, size);
|
2013-06-19 12:13:45 +00:00
|
|
|
p->h->buffer->ulength = size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-17 15:30:52 +00:00
|
|
|
if (p->h->context->debug == 1) {
|
2020-01-22 13:10:59 +00:00
|
|
|
if (p->owner)
|
2019-07-17 15:30:52 +00:00
|
|
|
grib_context_log(p->h->context, GRIB_LOG_DEBUG,
|
2020-01-22 13:10:59 +00:00
|
|
|
"Creating (%s)%s of %s at offset %d [len=%d]",
|
|
|
|
p->owner->name, a->name, creator->op, a->offset, len, p->block);
|
2019-07-17 15:30:52 +00:00
|
|
|
else
|
|
|
|
grib_context_log(p->h->context, GRIB_LOG_DEBUG,
|
2020-01-22 13:10:59 +00:00
|
|
|
"Creating root %s of %s at offset %d [len=%d]",
|
|
|
|
a->name, creator->op, a->offset, len, p->block);
|
2019-07-17 15:30:52 +00:00
|
|
|
}
|
2013-06-19 12:13:45 +00:00
|
|
|
|
|
|
|
return a;
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
static void link_same_attributes(grib_accessor* a, grib_accessor* b)
|
2015-12-30 14:39:02 +00:00
|
|
|
{
|
2020-01-22 13:10:59 +00:00
|
|
|
int i = 0;
|
|
|
|
int idx = 0;
|
|
|
|
grib_accessor* bAttribute = NULL;
|
|
|
|
if (a == NULL || b == NULL)
|
|
|
|
return;
|
|
|
|
if (!grib_accessor_has_attributes(b))
|
|
|
|
return;
|
|
|
|
while (i < MAX_ACCESSOR_ATTRIBUTES && a->attributes[i]) {
|
|
|
|
bAttribute = _grib_accessor_get_attribute(b, a->attributes[i]->name, &idx);
|
|
|
|
if (bAttribute)
|
|
|
|
a->attributes[i]->same = bAttribute;
|
2016-08-31 08:59:21 +00:00
|
|
|
i++;
|
|
|
|
}
|
2015-02-26 18:28:42 +00:00
|
|
|
}
|
|
|
|
|
2013-03-25 12:04:10 +00:00
|
|
|
void grib_push_accessor(grib_accessor* a, grib_block_of_accessors* l)
|
|
|
|
{
|
2013-06-19 12:13:45 +00:00
|
|
|
int id;
|
2017-06-05 11:20:33 +00:00
|
|
|
grib_handle* hand = grib_handle_of_accessor(a);
|
2013-06-19 12:13:45 +00:00
|
|
|
if (!l->first)
|
|
|
|
l->first = l->last = a;
|
2020-01-22 13:10:59 +00:00
|
|
|
else {
|
2013-06-19 12:13:45 +00:00
|
|
|
l->last->next = a;
|
2020-01-22 13:10:59 +00:00
|
|
|
a->previous = l->last;
|
2013-06-19 12:13:45 +00:00
|
|
|
}
|
|
|
|
l->last = a;
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2017-06-05 11:20:33 +00:00
|
|
|
if (hand->use_trie) {
|
2013-06-19 12:13:45 +00:00
|
|
|
if (*(a->all_names[0]) != '_') {
|
2020-01-22 13:10:59 +00:00
|
|
|
id = grib_hash_keys_get_id(a->context->keys, a->all_names[0]);
|
2017-06-05 11:20:33 +00:00
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
DebugAssert(id >= 0 && id < ACCESSORS_ARRAY_SIZE);
|
2017-06-05 11:20:33 +00:00
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
a->same = hand->accessors[id];
|
|
|
|
link_same_attributes(a, a->same);
|
|
|
|
hand->accessors[id] = a;
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
if (a->same == a) {
|
|
|
|
fprintf(stderr, "---> %s\n", a->name);
|
2013-06-19 12:13:45 +00:00
|
|
|
Assert(a->same != a);
|
|
|
|
}
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void grib_section_post_init(grib_section* s)
|
|
|
|
{
|
2013-06-19 12:13:45 +00:00
|
|
|
grib_accessor* a = s ? s->block->first : NULL;
|
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
while (a) {
|
|
|
|
grib_accessor_class* c = a->cclass;
|
|
|
|
if (c->post_init)
|
|
|
|
c->post_init(a);
|
2013-06-19 12:13:45 +00:00
|
|
|
if (a->sub_section)
|
|
|
|
grib_section_post_init(a->sub_section);
|
|
|
|
a = a->next;
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
int grib_section_adjust_sizes(grib_section* s, int update, int depth)
|
2013-03-25 12:04:10 +00:00
|
|
|
{
|
2020-01-22 13:10:59 +00:00
|
|
|
int err = 0;
|
2013-06-19 12:13:45 +00:00
|
|
|
grib_accessor* a = s ? s->block->first : NULL;
|
2020-01-22 13:10:59 +00:00
|
|
|
size_t length = update ? 0 : (s ? s->padding : 0);
|
|
|
|
size_t offset = (s && s->owner) ? s->owner->offset : 0;
|
2013-06-19 12:13:45 +00:00
|
|
|
int force_update = update > 1;
|
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
while (a) {
|
2013-06-19 12:13:45 +00:00
|
|
|
register long l;
|
|
|
|
/* grib_section_adjust_sizes(grib_get_sub_section(a),update,depth+1); */
|
2020-01-22 13:10:59 +00:00
|
|
|
err = grib_section_adjust_sizes(a->sub_section, update, depth + 1);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2019-07-17 15:30:52 +00:00
|
|
|
/*grib_context_log(a->context,GRIB_LOG_DEBUG,"grib_section_adjust_sizes: %s %ld [len=%ld] (depth=%d)",a->name,(long)a->offset,(long)a->length,depth);*/
|
2013-06-19 12:13:45 +00:00
|
|
|
|
|
|
|
l = a->length;
|
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
if (offset != a->offset) {
|
|
|
|
grib_context_log(a->context, GRIB_LOG_ERROR,
|
|
|
|
"Offset mismatch %s A->offset %ld offset %ld\n", a->name, (long)a->offset, (long)offset);
|
2013-06-19 12:13:45 +00:00
|
|
|
a->offset = offset;
|
2014-07-17 17:02:49 +00:00
|
|
|
return GRIB_DECODING_ERROR;
|
2013-06-19 12:13:45 +00:00
|
|
|
}
|
|
|
|
length += l;
|
|
|
|
offset += l;
|
|
|
|
a = a->next;
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
if (s) {
|
|
|
|
if (s->aclength) {
|
|
|
|
size_t len = 1;
|
|
|
|
long plen = 0;
|
|
|
|
int lret = grib_unpack_long(s->aclength, &plen, &len);
|
|
|
|
Assert(lret == GRIB_SUCCESS);
|
2013-06-19 12:13:45 +00:00
|
|
|
/* This happens when there is some padding */
|
2020-01-22 13:10:59 +00:00
|
|
|
if ((plen != length) || force_update) {
|
|
|
|
if (update) {
|
2013-06-19 12:13:45 +00:00
|
|
|
plen = length;
|
2020-01-22 13:10:59 +00:00
|
|
|
lret = grib_pack_long(s->aclength, &plen, &len);
|
2013-06-19 12:13:45 +00:00
|
|
|
Assert(lret == GRIB_SUCCESS);
|
|
|
|
s->padding = 0;
|
|
|
|
}
|
|
|
|
else {
|
2020-01-22 13:10:59 +00:00
|
|
|
if (!s->h->partial) {
|
|
|
|
if (length >= plen) {
|
|
|
|
grib_context_log(s->h->context, GRIB_LOG_ERROR, "Invalid size %ld found for %s, assuming %ld",
|
|
|
|
(long)plen, s->owner->name, (long)length);
|
2013-06-19 12:13:45 +00:00
|
|
|
plen = length;
|
|
|
|
}
|
|
|
|
s->padding = plen - length;
|
|
|
|
}
|
|
|
|
length = plen;
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
if (s->owner) {
|
2019-07-17 15:30:52 +00:00
|
|
|
/*grib_context_log(s->owner->context,GRIB_LOG_DEBUG,"grib_section_adjust_sizes: updating owner (%s->length old=%ld new=%ld)",s->owner->name,(long)s->owner->length,(long)length);*/
|
2016-08-31 08:59:21 +00:00
|
|
|
s->owner->length = length;
|
2015-06-08 14:12:30 +00:00
|
|
|
}
|
2013-06-19 12:13:45 +00:00
|
|
|
s->length = length;
|
|
|
|
}
|
2014-07-17 17:02:49 +00:00
|
|
|
return err;
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
int grib_get_block_length(grib_section* s, size_t* l)
|
2013-03-25 12:04:10 +00:00
|
|
|
{
|
2013-06-19 12:13:45 +00:00
|
|
|
*l = s->length;
|
|
|
|
return GRIB_SUCCESS;
|
2013-03-25 12:04:10 +00:00
|
|
|
#if 0
|
|
|
|
|
2013-06-19 12:13:45 +00:00
|
|
|
/* TODO: Because grib_pack_long takes a SIGNED value, we may have problems */
|
|
|
|
|
|
|
|
if(s->aclength)
|
|
|
|
{
|
|
|
|
size_t len = 1;
|
|
|
|
long plen = 0;
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-19 12:13:45 +00:00
|
|
|
int ret = grib_unpack_long(s->aclength, &plen, &len);
|
|
|
|
if(ret == GRIB_SUCCESS && plen != 0)
|
|
|
|
{
|
|
|
|
*l = plen;
|
|
|
|
return GRIB_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-19 12:13:45 +00:00
|
|
|
/* empty block */
|
|
|
|
if(s->block->first == NULL)
|
2013-03-25 12:04:10 +00:00
|
|
|
{
|
2013-06-19 12:13:45 +00:00
|
|
|
*l = 0;
|
|
|
|
return GRIB_SUCCESS;
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
2013-06-19 12:13:45 +00:00
|
|
|
/* no accessor for block length */
|
|
|
|
if(s->owner)
|
|
|
|
*l = grib_get_next_position_offset(s->block->last) - s->owner->offset;
|
|
|
|
else
|
|
|
|
*l = grib_get_next_position_offset(s->block->last);
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-19 12:13:45 +00:00
|
|
|
|
|
|
|
if(s->aclength)
|
|
|
|
{
|
|
|
|
size_t len = 1;
|
|
|
|
long plen = *l;
|
|
|
|
|
|
|
|
int ret = grib_pack_long(s->aclength, &plen, &len);
|
|
|
|
if(ret != GRIB_SUCCESS)
|
|
|
|
;
|
|
|
|
if(s->h->context->debug)
|
|
|
|
printf("SECTION updating length %ld %s\n",plen,s->owner->name);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2013-03-25 12:04:10 +00:00
|
|
|
if(s->aclength)
|
|
|
|
Assert(*l == plen);*/
|
|
|
|
|
2013-06-19 12:13:45 +00:00
|
|
|
return GRIB_SUCCESS;
|
2013-03-25 12:04:10 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
grib_accessor* find_paddings(grib_section* s)
|
|
|
|
{
|
2013-06-19 12:13:45 +00:00
|
|
|
grib_accessor* a = s ? s->block->first : NULL;
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
while (a) {
|
2013-06-19 12:13:45 +00:00
|
|
|
/* grib_accessor* p = find_paddings(grib_get_sub_section(a)); */
|
|
|
|
grib_accessor* p = find_paddings(a->sub_section);
|
2020-01-22 13:10:59 +00:00
|
|
|
if (p)
|
|
|
|
return p;
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2020-01-22 13:10:59 +00:00
|
|
|
if (grib_preferred_size(a, 0) != a->length)
|
2013-06-19 12:13:45 +00:00
|
|
|
return a;
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-19 12:13:45 +00:00
|
|
|
a = a->next;
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-19 12:13:45 +00:00
|
|
|
return NULL;
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void grib_update_paddings(grib_section* s)
|
|
|
|
{
|
2013-06-19 12:13:45 +00:00
|
|
|
grib_accessor* last = NULL;
|
|
|
|
grib_accessor* changed;
|
|
|
|
|
|
|
|
/* while((changed = find_paddings(s)) != NULL) */
|
2020-01-22 13:10:59 +00:00
|
|
|
while ((changed = find_paddings(s->h->root)) != NULL) {
|
2013-06-19 12:13:45 +00:00
|
|
|
Assert(changed != last);
|
2020-01-22 13:10:59 +00:00
|
|
|
grib_resize(changed, grib_preferred_size(changed, 0));
|
2013-06-19 12:13:45 +00:00
|
|
|
last = changed;
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|