1 /*
2 * (C) Copyright 2005- ECMWF.
3 *
4 * This software is licensed under the terms of the Apache Licence Version 2.0
5 * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6 *
7 * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
8 * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
9 */
10
11 #include "grib_api_internal.h"
12 /*
13 This is used by make_class.pl
14
15 START_CLASS_DEF
16 CLASS = accessor
17 SUPER = grib_accessor_class_bytes
18
19 IMPLEMENTS = next_offset
20 IMPLEMENTS = unpack_double;unpack_double_element
21 IMPLEMENTS = unpack_long
22 IMPLEMENTS = unpack_string
23 IMPLEMENTS = init;dump;update_size
24 MEMBERS=const char* tableReference
25 MEMBERS=const char* missing_value
26 MEMBERS=const char* offsetbsec
27 MEMBERS=const char* sLength
28 END_CLASS_DEF
29
30 */
31
32 /* START_CLASS_IMP */
33
34 /*
35
36 Don't edit anything between START_CLASS_IMP and END_CLASS_IMP
37 Instead edit values between START_CLASS_DEF and END_CLASS_DEF
38 or edit "accessor.class" and rerun ./make_class.pl
39
40 */
41
42 static int unpack_double(grib_accessor*, double* val, size_t* len);
43 static int unpack_long(grib_accessor*, long* val, size_t* len);
44 static int unpack_string(grib_accessor*, char*, size_t* len);
45 static long next_offset(grib_accessor*);
46 static void dump(grib_accessor*, grib_dumper*);
47 static void init(grib_accessor*, const long, grib_arguments*);
48 static void init_class(grib_accessor_class*);
49 static void update_size(grib_accessor*, size_t);
50 static int unpack_double_element(grib_accessor*, size_t i, double* val);
51
52 typedef struct grib_accessor_bitmap
53 {
54 grib_accessor att;
55 /* Members defined in gen */
56 /* Members defined in bytes */
57 /* Members defined in bitmap */
58 const char* tableReference;
59 const char* missing_value;
60 const char* offsetbsec;
61 const char* sLength;
62 } grib_accessor_bitmap;
63
64 extern grib_accessor_class* grib_accessor_class_bytes;
65
66 static grib_accessor_class _grib_accessor_class_bitmap = {
67 &grib_accessor_class_bytes, /* super */
68 "bitmap", /* name */
69 sizeof(grib_accessor_bitmap), /* size */
70 0, /* inited */
71 &init_class, /* init_class */
72 &init, /* init */
73 0, /* post_init */
74 0, /* free mem */
75 &dump, /* describes himself */
76 &next_offset, /* get length of section */
77 0, /* get length of string */
78 0, /* get number of values */
79 0, /* get number of bytes */
80 0, /* get offset to bytes */
81 0, /* get native type */
82 0, /* get sub_section */
83 0, /* grib_pack procedures long */
84 0, /* grib_pack procedures long */
85 0, /* grib_pack procedures long */
86 &unpack_long, /* grib_unpack procedures long */
87 0, /* grib_pack procedures double */
88 &unpack_double, /* grib_unpack procedures double */
89 0, /* grib_pack procedures string */
90 &unpack_string, /* grib_unpack procedures string */
91 0, /* grib_pack array procedures string */
92 0, /* grib_unpack array procedures string */
93 0, /* grib_pack procedures bytes */
94 0, /* grib_unpack procedures bytes */
95 0, /* pack_expression */
96 0, /* notify_change */
97 &update_size, /* update_size */
98 0, /* preferred_size */
99 0, /* resize */
100 0, /* nearest_smaller_value */
101 0, /* next accessor */
102 0, /* compare vs. another accessor */
103 &unpack_double_element, /* unpack only ith value */
104 0, /* unpack a subarray */
105 0, /* clear */
106 0, /* clone accessor */
107 };
108
109
110 grib_accessor_class* grib_accessor_class_bitmap = &_grib_accessor_class_bitmap;
111
112
init_class(grib_accessor_class * c)113 static void init_class(grib_accessor_class* c)
114 {
115 c->string_length = (*(c->super))->string_length;
116 c->value_count = (*(c->super))->value_count;
117 c->byte_count = (*(c->super))->byte_count;
118 c->byte_offset = (*(c->super))->byte_offset;
119 c->get_native_type = (*(c->super))->get_native_type;
120 c->sub_section = (*(c->super))->sub_section;
121 c->pack_missing = (*(c->super))->pack_missing;
122 c->is_missing = (*(c->super))->is_missing;
123 c->pack_long = (*(c->super))->pack_long;
124 c->pack_double = (*(c->super))->pack_double;
125 c->pack_string = (*(c->super))->pack_string;
126 c->pack_string_array = (*(c->super))->pack_string_array;
127 c->unpack_string_array = (*(c->super))->unpack_string_array;
128 c->pack_bytes = (*(c->super))->pack_bytes;
129 c->unpack_bytes = (*(c->super))->unpack_bytes;
130 c->pack_expression = (*(c->super))->pack_expression;
131 c->notify_change = (*(c->super))->notify_change;
132 c->preferred_size = (*(c->super))->preferred_size;
133 c->resize = (*(c->super))->resize;
134 c->nearest_smaller_value = (*(c->super))->nearest_smaller_value;
135 c->next = (*(c->super))->next;
136 c->compare = (*(c->super))->compare;
137 c->unpack_double_subarray = (*(c->super))->unpack_double_subarray;
138 c->clear = (*(c->super))->clear;
139 c->make_clone = (*(c->super))->make_clone;
140 }
141
142 /* END_CLASS_IMP */
143
144
compute_size(grib_accessor * a)145 static void compute_size(grib_accessor* a)
146 {
147 long slen = 0;
148 long off = 0;
149 grib_handle* hand = grib_handle_of_accessor(a);
150
151 grib_accessor_bitmap* self = (grib_accessor_bitmap*)a;
152 grib_get_long_internal(hand, self->offsetbsec, &off);
153 grib_get_long_internal(hand, self->sLength, &slen);
154
155 if (slen == 0) {
156 grib_accessor* seclen;
157 size_t size;
158 /* Assume reparsing */
159 Assert(hand->loader != 0);
160 if (hand->loader != 0) {
161 seclen = grib_find_accessor(hand, self->sLength);
162 Assert(seclen);
163 grib_get_block_length(seclen->parent, &size);
164 slen = size;
165 }
166 }
167
168 #if 0
169 printf("compute_size off=%ld slen=%ld a->offset=%ld\n",
170 (long)off,(long)slen,(long)a->offset);
171 #endif
172
173 a->length = off + (slen - a->offset);
174
175 if (a->length < 0) {
176 /* Assume reparsing */
177 /*Assert(hand->loader != 0);*/
178 a->length = 0;
179 }
180
181 Assert(a->length >= 0);
182 }
183
init(grib_accessor * a,const long len,grib_arguments * arg)184 static void init(grib_accessor* a, const long len, grib_arguments* arg)
185 {
186 grib_accessor_bitmap* self = (grib_accessor_bitmap*)a;
187 grib_handle* hand = grib_handle_of_accessor(a);
188 int n = 0;
189
190 self->tableReference = grib_arguments_get_name(hand, arg, n++);
191 self->missing_value = grib_arguments_get_name(hand, arg, n++);
192 self->offsetbsec = grib_arguments_get_name(hand, arg, n++);
193 self->sLength = grib_arguments_get_name(hand, arg, n++);
194
195 compute_size(a);
196 }
197
next_offset(grib_accessor * a)198 static long next_offset(grib_accessor* a)
199 {
200 return grib_byte_offset(a) + grib_byte_count(a);
201 }
202
dump(grib_accessor * a,grib_dumper * dumper)203 static void dump(grib_accessor* a, grib_dumper* dumper)
204 {
205 long len = 0;
206 char label[1024];
207
208 grib_value_count(a, &len);
209
210 sprintf(label, "Bitmap of %ld values", len);
211 grib_dump_bytes(dumper, a, label);
212 }
213
unpack_long(grib_accessor * a,long * val,size_t * len)214 static int unpack_long(grib_accessor* a, long* val, size_t* len)
215 {
216 long pos = a->offset * 8;
217 long tlen = 0;
218 long i = 0;
219 int err = 0;
220 grib_handle* hand = grib_handle_of_accessor(a);
221
222 err = grib_value_count(a, &tlen);
223 if (err)
224 return err;
225
226 if (*len < tlen) {
227 grib_context_log(a->context, GRIB_LOG_ERROR, "Wrong size for %s it contains %d values ", a->name, tlen);
228 *len = 0;
229 return GRIB_ARRAY_TOO_SMALL;
230 }
231
232 for (i = 0; i < tlen; i++) {
233 val[i] = (long)grib_decode_unsigned_long(hand->buffer->data, &pos, 1);
234 }
235 *len = tlen;
236 return GRIB_SUCCESS;
237 }
238
unpack_double(grib_accessor * a,double * val,size_t * len)239 static int unpack_double(grib_accessor* a, double* val, size_t* len)
240 {
241 long pos = a->offset * 8;
242 long tlen;
243 long i;
244 int err = 0;
245 grib_handle* hand = grib_handle_of_accessor(a);
246
247 err = grib_value_count(a, &tlen);
248 if (err)
249 return err;
250
251 if (*len < tlen) {
252 grib_context_log(a->context, GRIB_LOG_ERROR, "Wrong size for %s it contains %d values ", a->name, tlen);
253 *len = 0;
254 return GRIB_ARRAY_TOO_SMALL;
255 }
256
257 for (i = 0; i < tlen; i++) {
258 val[i] = (double)grib_decode_unsigned_long(hand->buffer->data, &pos, 1);
259 }
260 *len = tlen;
261 return GRIB_SUCCESS;
262 }
263
unpack_double_element(grib_accessor * a,size_t idx,double * val)264 static int unpack_double_element(grib_accessor* a, size_t idx, double* val)
265 {
266 long pos = a->offset * 8;
267
268 pos += idx;
269 *val = (double)grib_decode_unsigned_long(grib_handle_of_accessor(a)->buffer->data, &pos, 1);
270
271 return GRIB_SUCCESS;
272 }
273
update_size(grib_accessor * a,size_t s)274 static void update_size(grib_accessor* a, size_t s)
275 {
276 a->length = s;
277 }
278
unpack_string(grib_accessor * a,char * val,size_t * len)279 static int unpack_string(grib_accessor* a, char* val, size_t* len)
280 {
281 int i = 0;
282 grib_handle* hand = grib_handle_of_accessor(a);
283
284 if (len[0] < (a->length)) {
285 grib_context_log(a->context, GRIB_LOG_ERROR, "unpack_string: Wrong size (%d) for %s it contains %d values ", len[0], a->name, a->length);
286 len[0] = 0;
287 return GRIB_ARRAY_TOO_SMALL;
288 }
289
290 for (i = 0; i < a->length; i++)
291 val[i] = hand->buffer->data[a->offset + i];
292
293 len[0] = a->length;
294
295 return GRIB_SUCCESS;
296 }
297