File: multidef.c

package info (click to toggle)
metview 5.26.2-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 614,356 kB
  • sloc: cpp: 560,586; ansic: 44,641; xml: 19,933; f90: 17,984; sh: 7,454; python: 5,565; yacc: 2,318; lex: 1,372; perl: 701; makefile: 87
file content (132 lines) | stat: -rw-r--r-- 4,496 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
 * © Copyright 1996-2012 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.
 */

#include "mars.h"

/********************************************************/
/*                  Definition 190                      */
/********************************************************/
#ifdef FORTRAN_UPPERCASE
#define d_def_x_ D_DEF_X
#endif

#ifdef FORTRAN_NO_UNDERSCORE
#define d_def_x_ d_def_x
#endif

#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif

extern fortint d_def_x_(fortint* n, fortint* output, unsigned char* input);

#if defined(__cplusplus) || defined(c_plusplus)
}
#endif


static int decode_local_def(fortint number, fortint length, unsigned char* buffer, request* r, gribsec1* orig_s1) {
    int e = 0;
    griblocsec1 s1;
    gribsec1 sec1;

    CLEAR(s1);
    e = d_def_x_(&number, (fortint*)&s1, buffer);
    marslog(LOG_DBUG, "Calling decoder for definition %d, returns %d", number, e);
    if (e > length) {
        marslog(LOG_EROR, "Decoder D_DEF_%d returns %d (> %d from GRIB header)", number, e, length);
        return -7;
    }

    if (s1.ecmwf_local_id != number) {
        marslog(LOG_EROR, "Mistmatch in Multi-local definition");
        marslog(LOG_EROR, "Main GRIB header has local def. %d", number);
        marslog(LOG_EROR, "Local definition is %d", s1.ecmwf_local_id);
        return -7;
    }

    /* Fill the request with values from this local definition
       Copy the original GRIB section 1, then replace the contents
       with the just read local section 1
    */
    CLEAR(sec1);
    memcpy((unsigned char*)&sec1, (unsigned char*)orig_s1, sizeof(gribsec1));
    memcpy((unsigned char*)&(sec1.local), (unsigned char*)&s1, sizeof(s1));
    if ((e = localdefinition(&sec1, r)) != NOERR) {
        marslog(LOG_WARN, "Error %d when inspecting local definition %d", e, number);
        return e;
    }

    return e;
}

int decode_multi_local_definition_190(gribsec1* s1, request* r, char* grib) {
    int i                   = 0;
    int e                   = 0;
    int offset              = 0;
    unsigned char* startdef = (unsigned char*)&(s1->local.u.multi_definition_190.number) + sizeof(fortint) + (s1->local.u.multi_definition_190.number * sizeof(multilocaldef_190));

    for (i = 0; i < s1->local.u.multi_definition_190.number; ++i) {
        fortint defnumber = s1->local.u.multi_definition_190.def[i].number;
        fortint deflength = s1->local.u.multi_definition_190.def[i].length;

        unsigned char* localdef = (unsigned char*)startdef;
        localdef += offset;

        e = decode_local_def(defnumber, deflength, localdef, r, s1);
        if (e)
            return e;

        offset += deflength;
    }

    set_mars_class(&s1->local, r);
    set_mars_type(&s1->local, r);
    set_mars_stream(s1, &s1->local, r);
    set_mars_expver(&s1->local, r);

    return e;
}

/********************************************************/
/*                  Definition 192                      */
/********************************************************/
int decode_multi_local_definition(gribsec1* s1, request* r, char* grib) {
    int i      = 0;
    int e      = 0;
    int offset = 0;
    fortint* p = (fortint*)&(s1->local.u.multi_definition.localdef);

    marslog(LOG_DBUG, "Found %d defitions within def 192", s1->local.u.multi_definition.number);
    for (i = 0; i < s1->local.u.multi_definition.number; ++i) {
        fortint deflength = p[0];
        gribsec1 sec1;

        CLEAR(sec1);
        memcpy((unsigned char*)&sec1, (unsigned char*)s1, sizeof(gribsec1));
        memcpy((unsigned char*)&(sec1.local), (unsigned char*)&p[1], deflength * sizeof(fortint));

        marslog(LOG_DBUG, "Processing definition %d => ECMWF local definition %" D " [%" D "]", i, sec1.local.ecmwf_local_id, p[1]);

        if ((e = localdefinition(&sec1, r)) != NOERR) {
            marslog(LOG_WARN, "Error %d when inspecting local definition %" D "", e, sec1.local.ecmwf_local_id);
            return e;
        }

        p += deflength + 1;
    }

    set_mars_class(&s1->local, r);
    set_mars_type(&s1->local, r);
    set_mars_stream(s1, &s1->local, r);
    set_mars_expver(&s1->local, r);

    return e;
}