File: soffset.c

package info (click to toggle)
emoslib 000380%2Bdfsg-3
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 47,712 kB
  • ctags: 11,551
  • sloc: fortran: 89,643; ansic: 24,200; makefile: 370; sh: 355
file content (200 lines) | stat: -rwxr-xr-x 4,924 bytes parent folder | download | duplicates (2)
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/**
* Copyright 1981-2007 ECMWF
* 
* Licensed under the GNU Lesser General Public License which
* incorporates the terms and conditions of version 3 of the GNU
* General Public License.
* See LICENSE and gpl-3.0.txt for details.
*/

#include <stdio.h>
#include <string.h>
#include "fortint.h"


/* defines for FORTRAN subroutine */
#ifndef CRAY
#ifdef FORTRAN_NO_UNDERSCORE
#define SOFFSET soffset
#else
#define SOFFSET soffset_
#endif
#endif

#define ERROR(a,b) {perror(a);return b;}
#define GRIB 0x47524942
#define len3oct(p) ((((long)*(p))<<16) + (((long)*(p+1))<<8) + (long)*(p+2))
#define BIT1 0x80
#define BIT2 0x40
#define BIT3 0x20
#define BIT4 0x10
#define BIT5 0x08
#define BIT6 0x04
#define BIT7 0x02
#define BIT8 0x01

static int grab(unsigned char * , unsigned char * , long ,long ,long * );

fortint soffset_(
  unsigned char * buffer,
  fortint* is0,
  fortint* is1,
  fortint* is2,
  fortint* is3,
  fortint* is4,
  fortint* iedition) {
long s0, s1, s2, s3, s4, edition;
int large = 0;
int found = 0;
int code = 0;
long bytes_read = 0, advance;
unsigned char p, edit_num, flag23;
unsigned char size[3];
int section0 = 8, section1, section2, section3, section4;
long total;
unsigned char grp_7777[5];

/*  Read bytes until "GRIB" found */

    do
    {
        if( grab(buffer, &p, 1, 1, &bytes_read) != 0) return 1;
        code = ( (code << 8) + p ) & 0xFFFFFFFF;
        if (code == GRIB ) found = 1;
    } while ( ! found );
    s0 = bytes_read - 4;
    bytes_read = 4;

/*  Now find out which edition of GRIB is present (default is 1) */

    edition = 1;
    s1 = s0 + 8;
    if( (*(buffer+21-s0) == '\0') && (*(buffer+22-s0) == '\0') )
    {
        edition = -1;                            /* GRIB edition -1 */
        s1 = s0;
        section1 = 20;
        section0 = 4;
    }
    else
    {
        if( grab(buffer, size, 3, 1, &bytes_read) != 0) return 1;
        total = len3oct(size);
        if( total == 24 )
        {
/*          Move past the edition number */
            if( grab(buffer, &edit_num, 1, 1, &bytes_read) != 0) return 1;
            edition = 0;                         /* GRIB edition 0 */
            section1 = 24;
            s1 = s0 + 4;
            section0 = 4;
        }
    }

    if( edition == 1 )
    {
/*      See if it is an extra large (wave) product */
        if( total > 0x800000 ) {
            total = (total&0x7fffff) * 120;
            large = 1;
        }
/*      Move past the edition number */
        if( grab(buffer, &edit_num, 1, 1, &bytes_read) != 0) return 1;

/*      Read length of section 1 */
        if( grab(buffer, size, 3, 1, &bytes_read) != 0) return 1;
        section1 = len3oct(size);
    }

/*  Now figure out if sections 2/3 are present */

    advance = 4;
    bytes_read += advance;
    if( grab(buffer, &flag23, 1, 1, &bytes_read) != 0) return 1;
    section2 = flag23 & BIT1;
    section3 = flag23 & BIT2;

/*  Advance to end of section 1 */

    advance = section1 - (bytes_read - section0);
    bytes_read += advance;

/*  Read section 2 length if it is given*/

    if( section2 )
    {
        s2 = s0 + bytes_read;
        if( grab(buffer, size, 3, 1, &bytes_read) != 0) return 1;
        section2 = len3oct(size);
        advance = section2 - (bytes_read - section0 - section1);
        bytes_read += advance;
    }
    else
    {
        section2 = 0;
	s2 = 0;
    }

/*  Read section 3 length if it is given*/

    if( section3 )
    {
        s3 = s0 + bytes_read;
        if( grab(buffer, size, 3, 1, &bytes_read) != 0) return 1;
        section3 = len3oct(size);
        advance = section3 - (bytes_read - section0 - section1 - section2);
        bytes_read += advance;
    }
    else
    {
        section3 = 0;
	s3 = 0;
    }

/*  Read section 4 length */

    s4 = s0 + bytes_read;
    if( grab(buffer, size, 3, 1, &bytes_read) != 0) return 1;
    section4 = len3oct(size);
    if( large ) section4 = total + 3 - bytes_read - section4; 
    advance = section4 - (bytes_read - section0 - section1 - section2 - section3);
    bytes_read += advance;

/*  Check 7777 group is in the expected place */

    if( grab(buffer, grp_7777, 4, 1, &bytes_read) != 0) return 1;
    grp_7777[4] = '\0';
    if( strcmp((char *)grp_7777,"7777") != 0 )
      ERROR("7777 group not found", 15);
  

/*  Success! */
    *is0 = (fortint) s0;
    *is1 = (fortint) s1;
    *is2 = (fortint) s2;
    *is3 = (fortint) s3;
    *is4 = (fortint) s4;
    *iedition = (fortint) edition;
    return 0;
}

fortint soffset(
  unsigned char * buffer,
  fortint* is0,
  fortint* is1,
  fortint* is2,
  fortint* is3,
  fortint* is4,
  fortint* iedition) {
  return soffset_(buffer,is0,is1,is2,is3,is4,iedition);
}

static int grab(unsigned char * buffer, unsigned char * where, long size,long cnt,long * num_bytes_read)
{
long number = size*cnt;

    memcpy(where, (buffer+(*num_bytes_read)), number);
    *num_bytes_read += number;

    return 0;
}