eccodes/src/action_class_section.c

251 lines
7.4 KiB
C

/*
* (C) Copyright 2005- ECMWF.
*
* 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.
*/
/***************************************************************************
* Jean Baptiste Filippi - 01.11.2005 *
* Enrico Fucile
* *
***************************************************************************/
#include "grib_api_internal.h"
/*
This is used by make_class.pl
START_CLASS_DEF
CLASS = action
IMPLEMENTS = notify_change
IMPLEMENTS = reparse
IMPLEMENTS = xref
END_CLASS_DEF
*/
/* START_CLASS_IMP */
/*
Don't edit anything between START_CLASS_IMP and END_CLASS_IMP
Instead edit values between START_CLASS_DEF and END_CLASS_DEF
or edit "action.class" and rerun ./make_class.pl
*/
static void init_class(grib_action_class*);
static void xref(grib_action* d, FILE* f, const char* path);
static int notify_change(grib_action* a, grib_accessor* observer, grib_accessor* observed);
static grib_action* reparse(grib_action* a, grib_accessor* acc, int* doit);
typedef struct grib_action_section
{
grib_action act;
/* Members defined in section */
} grib_action_section;
static grib_action_class _grib_action_class_section = {
0, /* super */
"action_class_section", /* name */
sizeof(grib_action_section), /* size */
0, /* inited */
&init_class, /* init_class */
0, /* init */
0, /* destroy */
0, /* dump */
&xref, /* xref */
0, /* create_accessor*/
&notify_change, /* notify_change */
&reparse, /* reparse */
0, /* execute */
};
grib_action_class* grib_action_class_section = &_grib_action_class_section;
static void init_class(grib_action_class* c)
{
}
/* END_CLASS_IMP */
#if 0
/* new GCC compiler v4.5.0 complains function is defined but not used*/
static void check_sections(grib_section *s,grib_handle* h)
{
grib_accessor *a = s?s->block->first:NULL;
if(s) Assert(s->h == h);
while(a)
{
Assert(grib_handle_of_accessor(a) == h);
check_sections(a->sub_section,h);
a = a->next;
}
}
#endif
static int notify_change(grib_action* act, grib_accessor* notified,
grib_accessor* changed)
{
grib_loader loader = { 0, 0, 0, 0, 0 };
grib_section* old_section = NULL;
grib_handle* h = grib_handle_of_accessor(notified);
size_t len = 0;
size_t size = 0;
int err = 0;
grib_handle* tmp_handle;
int doit = 0;
grib_action* la = NULL;
if (h->context->debug > 0) {
char debug_str[1024] = {0,};
if (act->debug_info) {
sprintf(debug_str, " (%s)", act->debug_info);
}
grib_context_log(h->context,
GRIB_LOG_DEBUG, "------------- SECTION action %s (%s) is triggered by [%s]%s",
act->name, notified->name, changed->name, debug_str);
}
la = grib_action_reparse(act, notified, &doit);
old_section = notified->sub_section;
if (!old_section) return GRIB_INTERNAL_ERROR;
Assert(old_section->h == h);
/* printf("old = %p\n",(void*)old_section->branch); */
/* printf("new = %p\n",(void*)la); */
grib_context_log(h->context,
GRIB_LOG_DEBUG, "------------- DOIT %ld OLD %p NEW %p",
doit, old_section->branch, la);
if (!doit) {
if (la != NULL || old_section->branch != NULL)
if (la == old_section->branch) {
grib_context_log(h->context, GRIB_LOG_DEBUG, "IGNORING TRIGGER action %s (%s) is triggered %p", act->name, notified->name, (void*)la);
return GRIB_SUCCESS;
}
}
loader.list_is_resized = (la == old_section->branch);
if (!strcmp(changed->name, "GRIBEditionNumber"))
loader.changing_edition = 1;
else
loader.changing_edition = 0;
old_section->branch = la;
tmp_handle = grib_new_handle(h->context);
if (!tmp_handle)
return GRIB_OUT_OF_MEMORY;
tmp_handle->buffer = grib_create_growable_buffer(h->context);
Assert(tmp_handle->buffer); /* FIXME */
loader.data = h;
loader.lookup_long = grib_lookup_long_from_handle;
loader.init_accessor = grib_init_accessor_from_handle;
if (h->kid != NULL) {
return GRIB_INTERNAL_ERROR;
}
Assert(h->kid == NULL);
tmp_handle->loader = &loader;
tmp_handle->main = h;
h->kid = tmp_handle;
/* printf("tmp_handle- main %p %p\n",(void*)tmp_handle,(void*)h); */
grib_context_log(h->context, GRIB_LOG_DEBUG, "------------- CREATE TMP BLOCK act=%s notified=%s", act->name, notified->name);
tmp_handle->root = grib_section_create(tmp_handle, NULL);
tmp_handle->use_trie = 1;
err = grib_create_accessor(tmp_handle->root, act, &loader);
if (err) {
if (err == GRIB_NOT_FOUND && strcmp(act->name, "dataValues") == 0) {
/* FIXME: Allow this error. Needed when changing some packingTypes e.g. CCSDS to Simple */
/*err = GRIB_SUCCESS;*/
}
else {
return err;
}
}
err = grib_section_adjust_sizes(tmp_handle->root, 1, 0);
if (err)
return err;
grib_section_post_init(tmp_handle->root);
/* grib_recompute_sections_lengths(tmp_handle->root); */
grib_get_block_length(tmp_handle->root, &len);
grib_context_log(h->context, GRIB_LOG_DEBUG, "------------- TMP BLOCK IS sectlen=%d buffer=%d", len, tmp_handle->buffer->ulength);
#if 0
if(h->context->debug > 10)
grib_dump_content(tmp_handle,stdout,NULL,0,NULL);
#endif
/* Assert(tmp_handle->buffer->ulength == len); */
/* grib_empty_section(h->context,old_section); */
grib_buffer_replace(notified, tmp_handle->buffer->data, tmp_handle->buffer->ulength, 0, 1);
Assert(tmp_handle->root->block->first != NULL);
grib_swap_sections(old_section,
tmp_handle->root->block->first->sub_section);
Assert(tmp_handle->dependencies == NULL);
/* printf("grib_handle_delete %p\n",(void*)tmp_handle); */
grib_handle_delete(tmp_handle);
h->use_trie = 1;
h->trie_invalid = 1;
h->kid = NULL;
err = grib_section_adjust_sizes(h->root, 1, 0);
if (err)
return err;
grib_section_post_init(h->root);
grib_get_block_length(old_section, &size);
grib_context_log(h->context, GRIB_LOG_DEBUG, "------------- BLOCK SIZE %ld, buffer len=%ld", size, len);
if (h->context->debug > 10)
grib_dump_content(h, stdout, "debug", ~0, NULL);
Assert(size == len);
grib_update_paddings(old_section);
return err;
}
static grib_action* reparse(grib_action* a, grib_accessor* acc, int* doit)
{
/* Should be inherited */
printf("reparse should be inherited: %s\n", a->name);
Assert(1 == 0);
return 0;
}
static void xref(grib_action* d, FILE* f, const char* path)
{
}